/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2019-2022. All rights reserved.
 * Description: 外部输入解析文件
 * Author: hanwei
 * Create: 2019-04-25
 */

#include "externalinput.h"
#include <iostream>
#include <fstream>
#include <algorithm>
#include <adapter_rts.h>
#include "adapter_error_manager.h"
#include <thread>
#include <mutex>
#include <unistd.h>
#include "sal.h"
#include "externalinput_pub.h"

using namespace std;
using namespace hccl;

static std::mutex g_externalInputMutex;
static ExternalInput g_externalInput;  //  外部输入参数 （环境变量，配置文件）
static thread_local bool g_ifProf = true;
constexpr u32 NPU_NET_PROTOCOL_MAX_LEN = 127; // 最大HCCL_NPU_NET_PROTOCOL长度
constexpr u32 HCCL_QPS_PER_CONNECTION_MAX  = 32;  // HCCL 默认的rank 间QP个数（仅单算子下生效）

constexpr s32 HCCL_SEND_CQ_DEPTH_DEFAULT = (8 * 1024); // HCCL 默认的scq深度
constexpr s32 HCCL_SEND_CQ_DEPTH_MINNUM = 128; // HCCL scq深度最小值
constexpr s32 HCCL_SEND_CQ_DEPTH_MAXNUM = (32 * 1024); // HCCL scq深度最大值

const std::map<HcclAlgoType, std::string> HcclAlgoTypeMap = {
    {HcclAlgoType::HCCL_ALGO_TYPE_DEFAULT, "default"},
    {HcclAlgoType::HCCL_ALGO_TYPE_RING, "ring"},
    {HcclAlgoType::HCCL_ALGO_TYPE_PIPELINE, "pipeline"},
    {HcclAlgoType::HCCL_ALGO_TYPE_FULLMESH, "fullmesh"},
    {HcclAlgoType::HCCL_ALGO_TYPE_HDR, "HDR"},
    {HcclAlgoType::HCCL_ALGO_TYPE_PAIRWISE, "pairwise"},
    {HcclAlgoType::HCCL_ALGO_TYPE_NHR, "NHR"},
    {HcclAlgoType::HCCL_ALGO_TYPE_NHR_V1, "NHR_V1"},
    {HcclAlgoType::HCCL_ALGO_TYPE_AHC, "AHC"},
    {HcclAlgoType::HCCL_ALGO_TYPE_AHC_BROKE, "AHC_BROKE"},
    {HcclAlgoType::HCCL_ALGO_TYPE_NB, "NB"},
    {HcclAlgoType::HCCL_ALGO_TYPE_NULL, "null"},
    {HcclAlgoType::HCCL_ALGO_TYPE_NA, "NA"},
};

HcclResult InitExternalInput()
{
    std::lock_guard<std::mutex> lock(g_externalInputMutex);
    if (g_externalInput.initialized) {
        return HCCL_SUCCESS;
    }
    //  初始化环境变量参数
    CHK_RET(InitEnvVarParam());

    g_externalInput.initialized = true;

    return HCCL_SUCCESS;
}

HcclResult InitExternalInputHeterog()
{
    // 解析server间通信协议
    CHK_RET(InitParsesProtocol());

    return HCCL_SUCCESS;
}

HcclResult ResetInitState()
{
    g_externalInput.SetDefaultParams();
    return HCCL_SUCCESS;
}

HcclResult InitEnvVarParam()
{
    // 解析HCCL日志配置场景开关
    HcclResult ret = ParseLogConfig();
    RPT_ENV_ERR(ret != HCCL_SUCCESS, "EI0001", std::vector<std::string>({"env","tips"}),\
        std::vector<std::string>({"HCCL_LOG_CONFIG", "It must be 0 or 1."}));
    CHK_PRT_RET(ret != HCCL_SUCCESS,
        HCCL_ERROR("[Init][EnvVarParam]errNo[0x%016llx] In init env variable param, parse "\
            "HCCL_LOG_CONFIG failed. errorno[%d]", HCCL_ERROR_CODE(ret), ret), ret);

    // 解析hccl connect timeout 超时时间
    ret = ParseLinkConnTimeOut();
    RPT_ENV_ERR(ret != HCCL_SUCCESS, "EI0001", std::vector<std::string>({ "env", "tips" }),
        std::vector<std::string>({ "HCCL_CONNECT_TIMEOUT", "it should be a number greater than or "
        "equal to 120s and less than or equal to 7200s" }));
    CHK_PRT_RET(ret != HCCL_SUCCESS,
        HCCL_ERROR("[Init][EnvVarParam]errNo[0x%016llx] In init env variable param, parse link "\
            "time out failed. errorno[%d]", HCCL_ERROR_CODE(ret), ret), ret);

    // 解析hccl execute timeout 超时时间
    // 环境变量的解析在options解析之后, 如果options中配置了hccl execute timeout, 则不解析环境变量中的hccl execute timeout
    if (g_externalInput.execTimeOutSet != HcclExecTimeoutSet::HCCL_EXEC_TIMEOUT_SET_BY_OPTIONS) {
        ret = ParseExecTimeOut();
        CHK_PRT_RET(ret != HCCL_SUCCESS,
            HCCL_ERROR("[Init][EnvVarParam]errNo[0x%016llx] In init env variable param, parse "\
                "execute time out failed. errorno[%d]", HCCL_ERROR_CODE(ret), ret), ret);
    }

    // 解析server内通信方式
    ret = ParseIntraLinkType();
    RPT_ENV_ERR(ret != HCCL_SUCCESS, "EI0001", std::vector<std::string>({ "env", "tips" }),
        std::vector<std::string>({ "HCCL_INTRA_PCIE_ENABLE or HCCL_INTRA_ROCE_ENABLE",
        "Check whether HCCL_INTRA_PCIE_ENABLE or HCCL_INTRA_ROCE_ENABLE is set correctly"}));
    CHK_PRT_RET(ret != HCCL_SUCCESS,
        HCCL_ERROR("[Init][EnvVarParam]errNo[0x%016llx] In init env variable param, parse intra "\
            "comm type failed. errorno[%d]", HCCL_ERROR_CODE(ret), ret), ret);

    // 解析profiling 配置
    ret = ParseProfilingConfig();
    CHK_PRT_RET(ret != HCCL_SUCCESS,
        HCCL_ERROR("[Init][EnvVarParam]errNo[0x%016llx] In init env variable param, parse profiling "\
            "config failed. errorno[%d]", HCCL_ERROR_CODE(ret), ret), ret);

    // 解析whitelist switch配置
    ret = ParseHcclWhitelistSwitch();
    RPT_ENV_ERR(ret != HCCL_SUCCESS, "EI0001", std::vector<std::string>({"env","tips"}),\
        std::vector<std::string>({"HCCL_WHITELIST_DISABLE", "It must be 0 or 1."}));
    CHK_PRT_RET(ret != HCCL_SUCCESS,
        HCCL_ERROR("[Init][EnvVarParam]errNo[0x%016llx] In init env variable param, parse "\
            "whitelist switch failed. errorno[%d]", HCCL_ERROR_CODE(ret), ret), ret);

    // 解析whitelist file配置
    ret = ParseHcclWhitelistFilePath();
    RPT_ENV_ERR(ret != HCCL_SUCCESS, "EI0001", std::vector<std::string>({"env","tips"}),\
        std::vector<std::string>({"HCCL_WHITELIST_FILE", "Please check env config"}));
    CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[Init][EnvVarParam]errNo[0x%016llx] In init env variable param, "\
        "parse whitelist file failed. errorno[%d]", HCCL_ERROR_CODE(ret), ret), ret);

    // 解析rootinfo IF配置
    ret = ParseHcclIfIp();
    RPT_ENV_ERR(ret != HCCL_SUCCESS, "EI0001", std::vector<std::string>({"env","tips"}),\
        std::vector<std::string>({"HCCL_IF_IP", "it should be \"ip[%ifname]\""}));
    CHK_PRT_RET(ret != HCCL_SUCCESS,
        HCCL_ERROR("[Init][EnvVarParam]errNo[0x%016llx] In init env variable param, parse "\
            "rootInfo network interface failed. errorno[%d]", HCCL_ERROR_CODE(ret), ret), ret);

    // 解析Host Socket IfName配置
    ret = ParseHcclSocketIfName();
    RPT_ENV_ERR(ret != HCCL_SUCCESS, "EI0001", std::vector<std::string>({"env","tips"}),\
        std::vector<std::string>({"HCCL_SOCKET_IFNAME", "Please check env config"}));
    CHK_PRT_RET(ret != HCCL_SUCCESS,
        HCCL_ERROR("[Init][EnvVarParam]errNo[0x%016llx] In init env variable param, parse "\
            "host interface name failed. errorno[%d]", HCCL_ERROR_CODE(ret), ret), ret);

    ret = ParseHcclSocketFamily();
    RPT_ENV_ERR(ret, "EI0001", std::vector<std::string>({"env","tips"}),\
        std::vector<std::string>({"HCCL_SOCKET_FAMILY", "it should be \"AF_INET or AF_INET6\""}));
    CHK_PRT_RET(ret != HCCL_SUCCESS,
        HCCL_ERROR("[Init][EnvVarParam]errNo[0x%016llx] In init env variable param, parse "\
            "hccl socket family config failed. errorno[%d]", HCCL_ERROR_CODE(ret), ret), ret);

    // 解析device nic disable配置
    ret = ParseHcclDeviceNicDisable();
    RPT_ENV_ERR(ret != HCCL_SUCCESS, "EI0001", std::vector<std::string>({"env","tips"}),\
        std::vector<std::string>({"HCCL_DEVICE_NIC_DISABLE", "It must be 0 or 1."}));
    CHK_PRT_RET(ret != HCCL_SUCCESS,
        HCCL_ERROR("[Init][EnvVarParam]errNo[0x%016llx] In init env variable param, parse "\
            "device nic disable config failed. errorno[%d]", HCCL_ERROR_CODE(ret), ret), ret);

    // 解析host rdma enable配置
    ret = ParseHcclHostRdmaEnable();
    RPT_ENV_ERR(ret != HCCL_SUCCESS, "EI0001", std::vector<std::string>({"env","tips"}),\
        std::vector<std::string>({"HCCL_HOST_RDMA_ENABLE", "It must be 0 or 1."}));
    CHK_PRT_RET(ret != HCCL_SUCCESS,
        HCCL_ERROR("[Init][EnvVarParam]errNo[0x%016llx] In init env variable param, parse "\
            "host rdma enable config failed. errorno[%d]", HCCL_ERROR_CODE(ret), ret), ret);

    // 解析BASE端口
    ret = ParseHcclIfBasePort();
    RPT_ENV_ERR(ret != HCCL_SUCCESS, "EI0001", std::vector<std::string>({"env","tips"}),\
        std::vector<std::string>({"HCCL_IF_BASE_PORT", "Value range[1024,65520]"}));
    CHK_PRT_RET(ret != HCCL_SUCCESS,
        HCCL_ERROR("[Init][EnvVarParam]errNo[0x%016llx] In init env variable param, parse "\
            "IF base port config failed. errorno[%d]", HCCL_ERROR_CODE(ret), ret), ret);

    // 解析算法配置
    ret = ParseHcclAlgo();
    RPT_ENV_ERR(ret != HCCL_SUCCESS, "EI0001", std::vector<std::string>({"env","tips"}),\
        std::vector<std::string>({"HCCL_ALGO",
            "expect: level0:NA;level1:<algo> or <op0>=level0:NA;level1:<algo0>/<op1>=level0:NA;level1:<algo1>"}));
    CHK_PRT_RET(ret != HCCL_SUCCESS,
        HCCL_ERROR("[Init][EnvVarParam]errNo[0x%016llx] In init env variable param, parse "\
            "hccl algorithm config failed. errorno[%d]", HCCL_ERROR_CODE(ret), ret), ret);

    // 解析Cann版本
    // CANN版本的校验不影响HCCL业务，所以解析过程中不返回错误
    (void)ParseCannVersion();
    // 解析高性能算法开关
    (void)ParseHighPerfEnable();

    // 解析RDMATrafficClass
    ret = ParseRDMATrafficClass();
    RPT_ENV_ERR(ret != HCCL_SUCCESS, "EI0001", std::vector<std::string>({"env","tips"}),\
        std::vector<std::string>({"HCCL_RDMA_TC", "Value range[0, 255], Must be a multiple of 4"}));
    CHK_PRT_RET(ret != HCCL_SUCCESS,
        HCCL_ERROR("[Init][EnvVarParam]errNo[0x%016llx] In init env variable param, parse "\
            "HCCL_RDMA_TC failed. errorno[%d]", HCCL_ERROR_CODE(ret), ret), ret);

    // 解析RDMAServerLevel
    ret = ParseRDMAServerLevel();
    RPT_ENV_ERR(ret != HCCL_SUCCESS, "EI0001", std::vector<std::string>({"env","tips"}),\
        std::vector<std::string>({"HCCL_RDMA_SL", "Value range[0, 7]"}));
    CHK_PRT_RET(ret != HCCL_SUCCESS,
        HCCL_ERROR("[Init][EnvVarParam]errNo[0x%016llx] In init env variable param, parse "\
            "HCCL_RDMA_SL failed. errorno[%d]", HCCL_ERROR_CODE(ret), ret), ret);

    // 解析RDMATimeOut
    std::pair<u32, u32> rdmaTimeOutRange;
    ret = ParseRDMATimeOut(rdmaTimeOutRange);
    std::string vaildRange =
        "Value range[" + std::to_string(rdmaTimeOutRange.first) + " ," + std::to_string(rdmaTimeOutRange.second) + "]";
    RPT_ENV_ERR(ret != HCCL_SUCCESS, "EI0001", std::vector<std::string>({"env","tips"}),\
        std::vector<std::string>({"HCCL_RDMA_TIMEOUT", vaildRange}));
    CHK_PRT_RET(ret != HCCL_SUCCESS,
        HCCL_ERROR("[Init][EnvVarParam]errNo[0x%016llx] In init env variable param, parse "\
            "HCCL_RDMA_TIMEOUT failed. errorno[%d]", HCCL_ERROR_CODE(ret), ret), ret);

    // 解析RDMARetryCnt
    ret = ParseRDMARetryCnt();
    RPT_ENV_ERR(ret != HCCL_SUCCESS, "EI0001", std::vector<std::string>({"env","tips"}),\
        std::vector<std::string>({"HCCL_RDMA_RETRY_CNT", "Value range[1, 7]"}));
    CHK_PRT_RET(ret != HCCL_SUCCESS,
        HCCL_ERROR("[Init][EnvVarParam]errNo[0x%016llx] In init env variable param, parse "\
            "HCCL_RDMA_RETRY_CNT failed. errorno[%d]", HCCL_ERROR_CODE(ret), ret), ret);

    // 解析cclbufersize
    ret = ParseCclBufferSize();
    RPT_ENV_ERR(ret != HCCL_SUCCESS, "EI0001", std::vector<std::string>({"env","tips"}),\
        std::vector<std::string>({"HCCL_BUFFSIZE", "Value should be equal to or greater than 1(MB)."}));
    CHK_PRT_RET(ret != HCCL_SUCCESS,
        HCCL_ERROR("[Init][EnvVarParam]errNo[0x%016llx] In init env variable param, parse "\
            "HCCL_BUFFSIZE failed. errorno[%d]", HCCL_ERROR_CODE(ret), ret), ret);

    // 解析单算子模式是否使用FFTS PLUS模式
    ret = ParseHcclOpBasedFFTSModeEnable();
    RPT_ENV_ERR(ret != HCCL_SUCCESS, "EI0001", std::vector<std::string>({"env","tips"}),\
        std::vector<std::string>({"HCCL_OP_BASE_FFTS_MODE_ENABLE", "Value should be true or false."}));
    CHK_PRT_RET(ret != HCCL_SUCCESS,
        HCCL_ERROR("[Init][EnvVarParam]errNo[0x%016llx] In init env variable param, parse "\
            "HCCL_OP_BASE_FFTS_MODE_ENABLE failed. errorno[%d]", HCCL_ERROR_CODE(ret), ret), ret);

    // 解析hcclDeterministic,是否为确定性计算
    ret = ParseDeterministic();
    RPT_ENV_ERR(ret != HCCL_SUCCESS, "EI0001", std::vector<std::string>({"env","tips"}),\
        std::vector<std::string>({"HCCL_DETERMINISTIC", "Value should be true or false."}));
    CHK_PRT_RET(ret != HCCL_SUCCESS,
        HCCL_ERROR("[Init][EnvVarParam]errNo[0x%016llx] In init env variable param, parse "\
            "HCCL_DETERMINISTIC failed. errorno[%d]", HCCL_ERROR_CODE(ret), ret), ret);

    // 解析ffts+模式（子任务粒度）下task_exception_handler开关
    ret = ParseTaskExceptionSwitch();
    RPT_ENV_ERR(ret != HCCL_SUCCESS, "EI0001", std::vector<std::string>({"env","tips"}),\
        std::vector<std::string>({"HCCL_DIAGNOSE_ENABLE", "It must be 0 or 1."}));
    CHK_PRT_RET(ret != HCCL_SUCCESS,
        HCCL_ERROR("[Init][EnvVarParam]errNo[0x%016llx] In init env variable param, parse "\
            "HCCL_DIAGNOSE_ENABLE failed. errorno[%d]", HCCL_ERROR_CODE(ret), ret), ret);

    // 解析Entry日志开关
    ret = ParseEntryLogEnable();
    RPT_ENV_ERR(ret != HCCL_SUCCESS, "EI0001", std::vector<std::string>({"env","tips"}),\
        std::vector<std::string>({"HCCL_ENTRY_LOG_ENABLE", "It must be 0 or 1."}));
    CHK_PRT_RET(ret != HCCL_SUCCESS,
        HCCL_ERROR("[Init][EnvVarParam]errNo[0x%016llx] In init env variable param, parse "\
            "HCCL_ENTRY_LOG_ENABLE failed. errorno[%d]", HCCL_ERROR_CODE(ret), ret), ret);

    // 解析超节点内节点间链路选择开关
    ret = ParseInterLinkType();
    RPT_ENV_ERR(ret != HCCL_SUCCESS, "EI0001", std::vector<std::string>({"env","tips"}),\
        std::vector<std::string>({"HCCL_INTER_HCCS_DISABLE", "Value should be true or false."}));
    CHK_PRT_RET(ret != HCCL_SUCCESS,
        HCCL_ERROR("[Init][EnvVarParam]errNo[0x%016llx] In init env variable param, parse "\
            "HCCL_INTER_HCCS_DISABLE failed. errorno[%d]", HCCL_ERROR_CODE(ret), ret), ret);

    // 解析超节点内节点间控制面通信选择开关
    ret = ParseInterVnicDisable();
    RPT_ENV_ERR(ret != HCCL_SUCCESS, "EI0001", std::vector<std::string>({"env","tips"}),\
        std::vector<std::string>({"HCCL_INTER_VNIC_DISABLE", "Value should be true or false."}));
    CHK_PRT_RET(ret != HCCL_SUCCESS,
        HCCL_ERROR("[Init][EnvVarParam]errNo[0x%016llx] In init env variable param, parse "\
            "HCCL_INTER_VNIC_DISABLE failed. errorno[%d]", HCCL_ERROR_CODE(ret), ret), ret);

    ret = ParseOpExpansion();
    RPT_ENV_ERR(ret != HCCL_SUCCESS, "EI0001", std::vector<std::string>({"env","tips"}),\
        std::vector<std::string>({"HCCL_OP_EXPANSION_MODE", "it should be \"AI_CPU\""}));
    CHK_PRT_RET(ret != HCCL_SUCCESS,
        HCCL_ERROR("[Init][EnvVarParam]errNo[0x%016llx] In init env variable param, parse "\
            "HCCL_OP_EXPANSION_MODE failed. errorno[%d]", HCCL_ERROR_CODE(ret), ret), ret);

    // 解析MC2 DEBUG模式
    ret = ParseMc2DebugMode();
    RPT_ENV_ERR(ret != HCCL_SUCCESS, "EI0001", std::vector<std::string>({"env","tips"}),\
        std::vector<std::string>({"ASCEND_MC2_DEBUG_MODE", "It must be 1 or 4 or 8 or 16."}));
    CHK_PRT_RET(ret != HCCL_SUCCESS,
        HCCL_ERROR("[Init][EnvVarParam]errNo[0x%016llx] In init env variable param, parse "\
            "ASCEND_MC2_DEBUG_MODE failed. errorno[%d]", HCCL_ERROR_CODE(ret), ret), ret);

    // 解析rank 间的QP个数
    ret = ParseRdmaQpsPerConnection();
    RPT_ENV_ERR(ret != HCCL_SUCCESS, "EI0001", std::vector<std::string>({"env","tips"}),\
        std::vector<std::string>({"HCCL_RDMA_QPS_PER_CONNECTION", "The allowed value range is [1, 32], "\
        "but the recommended value range is [1, 8]."}));
    CHK_PRT_RET(ret != HCCL_SUCCESS,
        HCCL_ERROR("[Init][EnvVarParam]errNo[0x%016llx] In init env variable param, parse "\
            "HCCL_RDMA_QPS_PER_CONNECTION(range[1,32]) failed. errorno[%d]", HCCL_ERROR_CODE(ret), ret), ret);

    // 解析rank 间多QP切分门限
    ret = ParseMultiQpThreshold();
    RPT_ENV_ERR(ret != HCCL_SUCCESS, "EI0001", std::vector<std::string>({"env","tips"}),\
        std::vector<std::string>({"HCCL_MULTI_QP_THRESHOLD", "It should be larger than 0, less than 8193."}));
    CHK_PRT_RET(ret != HCCL_SUCCESS,
        HCCL_ERROR("[Init][EnvVarParam]errNo[0x%016llx] In init env variable param, parse "\
            "HCCL_MULTI_QP_THRESHOLD(range[1,8192]) failed. errorno[%d]", HCCL_ERROR_CODE(ret), ret), ret);

    // 解析RDMA和SDMA并发使能开关，此处理需要在ParseOpExpansion()之后
    ret = ParseRdmaSdmaConcurrentEnable();
    RPT_ENV_ERR(ret != HCCL_SUCCESS, "EI0001", std::vector<std::string>({"env","tips"}),\
        std::vector<std::string>({"HCCL_CONCURRENT_ENABLE", "It must be 0 or 1."}));
    CHK_PRT_RET(ret != HCCL_SUCCESS,
        HCCL_ERROR("[Init][EnvVarParam]errNo[0x%016llx] In init env variable param, parse "\
        "HCCL_CONCURRENT_ENABLE failed. errorno[%d]", HCCL_ERROR_CODE(ret), ret), ret);

#ifndef CCL_KERNEL_AICPU
    // 解析重执行设置
    ret = ParseRetryEnable();
    RPT_ENV_ERR(ret != HCCL_SUCCESS, "EI0001", std::vector<std::string>({"env","tips"}),\
        std::vector<std::string>({"HCCL_OP_RETRY_ENABLE", "Value should be 0 or 1."}));
    CHK_PRT_RET(ret != HCCL_SUCCESS,
        HCCL_ERROR("[Init][EnvVarParam]errNo[0x%016llx] In init env variable param, parse "\
            "HCCL_OP_RETRY_ENABLE failed. errorno[%d]", HCCL_ERROR_CODE(ret), ret), ret);
#endif

    ret = ParseSendCqDepth();
    RPT_ENV_ERR(ret != HCCL_SUCCESS, "EI0001", std::vector<std::string>({"env","tips"}),\
        std::vector<std::string>({"HCCL_SEND_CQ_DEPTH", "It should be larger than 128, less than 32768."}));
    CHK_PRT_RET(ret != HCCL_SUCCESS,
        HCCL_ERROR("[Init][EnvVarParam]errNo[0x%016llx] In init env variable param, parse "\
            "HCCL_SEND_CQ_DEPTH(range[128,32768]) failed. errorno[%d]", HCCL_ERROR_CODE(ret), ret), ret);

    ret = ParseDFTPrintLevel();
    RPT_ENV_ERR(ret != HCCL_SUCCESS, "EI0001", std::vector<std::string>({"env","tips"}),\
        std::vector<std::string>({"HCCL_DFT", "export HCCL_DFT = \"OP_TRACE:0\""}));
    CHK_PRT_RET(ret != HCCL_SUCCESS,
        HCCL_ERROR("[Init][EnvVarParam]errNo[0x%016llx] In init env variable param, parse "\
            "HCCL_DFT failed. errorno[%d]", HCCL_ERROR_CODE(ret), ret), ret);

    ret = ParseOpCounterEnable();
    RPT_ENV_ERR(ret != HCCL_SUCCESS, "EI0001", std::vector<std::string>({"env","tips"}),\
        std::vector<std::string>({"HCCL_OP_COUNTER_ENABLE", "Value should be 0 or 1."}));
    CHK_PRT_RET(ret != HCCL_SUCCESS,
        HCCL_ERROR("[Init][EnvVarParam]errNo[0x%016llx] In init env variable param, parse "\
            "HCCL_OP_COUNTER_ENABLE failed. errorno[%d]", HCCL_ERROR_CODE(ret), ret), ret);

#ifndef CCL_KERNEL_AICPU
    // 解析重执行最大尝试次数 重执行间隔时间 首次重执行等待时间 */
    ret = ParseRetryParams();
    RPT_ENV_ERR(ret != HCCL_SUCCESS, "EI0001", std::vector<std::string>({"env","tips"}),\
        std::vector<std::string>({"HCCL_OP_RETRY_PARAMS", "value format must be: \"MaxCnt:cnt,HoldTime:time,IntervalTime:time\"."\
        "cnt range is [1, 10], time range is [0, 60000]"}));
    CHK_PRT_RET(ret != HCCL_SUCCESS,
        HCCL_ERROR("[Init][EnvVarParam]errNo[0x%016llx] In init env variable param, parse "\
            "HCCL_OP_RETRY_PARAMS failed. errorno[%d]", HCCL_ERROR_CODE(ret), ret), ret);
#endif

    ret = ParseLogicSuperPodId();
    RPT_ENV_ERR(ret != HCCL_SUCCESS, "EI0001", std::vector<std::string>({"env","tips"}),\
        std::vector<std::string>({"HCCL_LOGIC_SUPERPOD_ID", "length must be less than 128"}));
    CHK_PRT_RET(ret != HCCL_SUCCESS,
        HCCL_ERROR("[Init][EnvVarParam]errNo[0x%016llx] In init env variable param, parse "\
            "HCCL_LOGIC_SUPERPOD_ID failed. errorno[%d]", HCCL_ERROR_CODE(ret), ret), ret);

    ret = ParseStuckDetectTime();
    RPT_ENV_ERR(ret != HCCL_SUCCESS, "EI0001", std::vector<std::string>({ "env", "tips" }),
        std::vector<std::string>({ "HCCL_STUCK_DETECT_TIME",
        "When HCCL_EXEC_TIMEOUT is greater than or equal to 60, it should be a number greater than or equal to 60s and "
        "less than or equal to HCCL_EXEC_TIMEOUT. When HCCL_EXEC_TIMEOUT is less than 60, it should is 60." }));
    CHK_PRT_RET(ret != HCCL_SUCCESS,
        HCCL_ERROR("[Init][EnvVarParam]errNo[0x%016llx] In init env variable param, parse stuck "\
            "detect time failed. errorno[%d]", HCCL_ERROR_CODE(ret), ret), ret);

    ret = ParseRdmaFastPost();
    RPT_ENV_ERR(ret != HCCL_SUCCESS, "EI0001", std::vector<std::string>({"env","tips"}),\
        std::vector<std::string>({"HCCL_RDMA_PCIE_DIRECT_POST_NOSTRICT", "Value should be true or false."}));
    CHK_PRT_RET(ret != HCCL_SUCCESS,
        HCCL_ERROR("[Init][EnvVarParam]errNo[0x%016llx] In init env variable param, parse "\
            "HCCL_RDMA_PCIE_DIRECT_POST_NOSTRICT failed. errorno[%d]", HCCL_ERROR_CODE(ret), ret), ret);

    // 解析多QP源端口号配置文件路径
    ret = ParseMultiQpSrcPortConfigPath();
    RPT_ENV_ERR(ret != HCCL_SUCCESS, "EI0001", std::vector<std::string>({"env","tips"}),\
        std::vector<std::string>({"HCCL_RDMA_QP_PORT_CONFIG_PATH", "Please check env config"}));
    CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[Init][EnvVarParam]errNo[0x%016llx] In init env variable param, "\
        "parse MultiQpSrcPortConfigPath failed. errorno[%d]", HCCL_ERROR_CODE(ret), ret), ret);

    return HCCL_SUCCESS;
}

HcclResult ParseRdmaFastPost()
{
    std::string rdmaFastPostEnv = SalGetEnv("HCCL_RDMA_PCIE_DIRECT_POST_NOSTRICT");
    if (rdmaFastPostEnv == "EmptyString") {
        HCCL_RUN_INFO("HCCL_RDMA_PCIE_DIRECT_POST_NOSTRICT set by default to [%s], rdmaFastPost is [%d]",
            rdmaFastPostEnv.c_str(), g_externalInput.rdmaFastPost);
        return HCCL_SUCCESS;
    }
    std::transform(rdmaFastPostEnv.begin(), rdmaFastPostEnv.end(), rdmaFastPostEnv.begin(), ::toupper);
    if (rdmaFastPostEnv == "TRUE") {
        g_externalInput.rdmaFastPost = true;
    } else if(rdmaFastPostEnv == "FALSE") {
        g_externalInput.rdmaFastPost = false;
    } else {
        HCCL_ERROR("HCCL_RDMA_PCIE_DIRECT_POST_NOSTRICT is set to [%s], which is incorrect. Please check",
            rdmaFastPostEnv.c_str());
        return HCCL_E_PARA;
    }
    HCCL_RUN_INFO("HCCL_RDMA_PCIE_DIRECT_POST_NOSTRICT set by environment to [%s], rdmaFastPost is [%d].",
        rdmaFastPostEnv.c_str(), g_externalInput.rdmaFastPost);
    return HCCL_SUCCESS;
}

HcclResult ParseExecTimeOut()
{
    std::string execTimeOutEnv = SalGetEnv("HCCL_EXEC_TIMEOUT");
    if (execTimeOutEnv == "EmptyString") {
        HCCL_RUN_INFO("HCCL_EXEC_TIMEOUT set by default to [%d]s", NOTIFY_DEFAULT_WAIT_TIME);
        return HCCL_SUCCESS;
    }

    // 校验环境变量长度
    bool isEnvLenValid = CheckEnvLen(execTimeOutEnv.c_str(), MAX_LEN_OF_DIGIT_ENV);

    CHK_PRT_RET(!isEnvLenValid,
        HCCL_ERROR("[Parse][ExecuteTimeOut]errNo[0x%016llx] Invalid ExecuteTimeOut env len, len is bigger than "\
            "[%u]. errorno[%d]", HCCL_ERROR_CODE(HCCL_E_PARA), MAX_LEN_OF_DIGIT_ENV, HCCL_E_PARA), HCCL_E_PARA);
    CHK_RET(SetHccLExecTimeOut(execTimeOutEnv.c_str(), HcclExecTimeoutSet::HCCL_EXEC_TIMEOUT_SET_BY_ENV));

    return HCCL_SUCCESS;
}

HcclResult ParseHighPerfEnable()
{
    std::string highPerfEnv = SalGetEnv("HCCL_HIGH_PERF_ENABLE");
    s32 highPerfEnable = 0;

    if (highPerfEnv != "EmptyString") {
        // 校验环境变量长度
        bool isEnvLenValid = CheckEnvLen(highPerfEnv.c_str(), MAX_LEN_OF_DIGIT_ENV);
        CHK_PRT_RET(!isEnvLenValid,
            HCCL_ERROR("[Parse][HighPerfEnable]errNo[0x%016llx] Invalid HighPerfEnable env len, len is bigger than "\
                "[%u]. errorno[%d]", HCCL_ERROR_CODE(HCCL_E_PARA), MAX_LEN_OF_DIGIT_ENV, HCCL_E_PARA), HCCL_E_PARA);

        CHK_RET(IsAllDigit(highPerfEnv.c_str()));
        CHK_RET(SalStrToInt(highPerfEnv, HCCL_BASE_DECIMAL, highPerfEnable));
        // 资料未公开的环境变量，不能通过默认日志级别输出，调整为info级别
        HCCL_INFO("HCCL_HIGH_PERF_ENABLE set by environment to [%d]", highPerfEnable);
    } else {
        // 资料未公开的环境变量，不能通过默认日志级别输出，调整为info级别
        HCCL_INFO("HCCL_HIGH_PERF_ENABLE set by default to [%d]", highPerfEnable);
    }
    g_externalInput.highPerfEnable = highPerfEnable;
    return HCCL_SUCCESS;
}

HcclResult ParseLinkConnTimeOut()
{
    std::string timeOutEnv = SalGetEnv("HCCL_CONNECT_TIMEOUT");
    s32 timeOut = HCCL_LINK_TIME_OUT_S;

    if (timeOutEnv != "EmptyString") {
        // 校验环境变量长度
        bool isEnvLenValid = CheckEnvLen(timeOutEnv.c_str(), MAX_LEN_OF_DIGIT_ENV);
        CHK_PRT_RET(!isEnvLenValid,
            HCCL_ERROR("[Parse][LinkConnTimeOut]errNo[0x%016llx] Invalid LinkConnTimeOut env len, len is bigger than "\
                "[%u]. errorno[%d]", HCCL_ERROR_CODE(HCCL_E_PARA), MAX_LEN_OF_DIGIT_ENV, HCCL_E_PARA), HCCL_E_PARA);

        CHK_RET(IsAllDigit(timeOutEnv.c_str()));
        HcclResult ret = SalStrToInt(timeOutEnv, HCCL_BASE_DECIMAL, timeOut);
        // 若转换出错或者设置的超时时间小于2分钟或大于2小时，报错并设为默认值
        if (ret !=  HCCL_SUCCESS || (timeOut < HCCL_MIN_LINK_TIME_OUT_S) || (timeOut > HCCL_MAX_LINK_TIME_OUT_S)) {
            HCCL_ERROR("[Parse][LinkConnTimeOut]environmental variable HCCL_CONNECT_TIMEOUT error, errNo[0x%016llx]" \
                "timeOutEnv[%s] timeRange[%d,%d]",
                HCOM_ERROR_CODE(ret), timeOutEnv.c_str(), HCCL_MIN_LINK_TIME_OUT_S, HCCL_MAX_LINK_TIME_OUT_S);
            g_externalInput.linkTimeOut = HCCL_LINK_TIME_OUT_S;
            return HCCL_E_PARA;
        }
        HCCL_RUN_INFO("HCCL_CONNECT_TIMEOUT set by environment to [%d]s", timeOut);
    } else {
        HCCL_RUN_INFO("HCCL_CONNECT_TIMEOUT set by default to [%d]s", timeOut);
    }

    g_externalInput.linkTimeOut = timeOut;
    return HCCL_SUCCESS;
}

HcclResult GetIntraLinkTypeDigit(std::string &intraCommStr, u32 &intraCommDig)
{
    CHK_RET(IsAllDigit(intraCommStr.c_str()));
    CHK_RET(SalStrToULong(intraCommStr.c_str(), HCCL_BASE_DECIMAL, intraCommDig));

    if ((intraCommDig != 0) && (intraCommDig != 1)) { // 判断转换后的数字是否为0或1
        HCCL_ERROR("[Get][IntraLinkTypeDigit]environmental digit variable error, intraCommDig[%u]", intraCommDig);
        return HCCL_E_PARA;
    }
    return HCCL_SUCCESS;
}

HcclResult ParseDeterministic()
{
    std::string hcclDeterministicEnv = SalGetEnv("HCCL_DETERMINISTIC");
    if (hcclDeterministicEnv == "EmptyString") {
        HCCL_INFO("HCCL_DETERMINISTIC set by default to [false]");
        return HCCL_SUCCESS;
    }

    std::transform(hcclDeterministicEnv.begin(), hcclDeterministicEnv.end(), hcclDeterministicEnv.begin(), ::toupper);
    if ("FALSE" == hcclDeterministicEnv) {
        g_externalInput.hcclDeterministic = false;
    } else if ("TRUE" == hcclDeterministicEnv) {
        g_externalInput.hcclDeterministic = true;
    } else {
        HCCL_ERROR("HCCL_DETERMINISTIC is set to [%s], which is incorrect. Please check", hcclDeterministicEnv.c_str());
        return HCCL_E_PARA;
    }
    // 资料未公开的环境变量，不能通过默认日志级别输出，调整为info级别
    HCCL_INFO("HCCL_DETERMINISTIC set by environment to [%s]", hcclDeterministicEnv.c_str());
    return HCCL_SUCCESS;
}

HcclResult ParseIntraLinkType()
{
    std::string intraPcieEnv = SalGetEnv("HCCL_INTRA_PCIE_ENABLE");
    std::string intraRoceEnv = SalGetEnv("HCCL_INTRA_ROCE_ENABLE");
    u32 intraPcie = 1; // 保存pcie环境变量的解析数字
    u32 intraRoce = 0; // 保存roce环境变量的解析数字

    // 两个通信域环境变量均未设置，默认走pcie
    if (intraPcieEnv == "EmptyString" && intraRoceEnv == "EmptyString") {
        HCCL_RUN_INFO("HCCL_INTRA_PCIE_ENABLE set by default to [%u], HCCL_INTRA_ROCE_ENABLE set by default to [%u]",
            intraPcie, intraRoce);
        return HCCL_SUCCESS;
    }

    if (intraPcieEnv != "EmptyString") { // 解析HCCL_INTRA_PCIE_ENABLE为数字
        // 校验环境变量长度
        bool isEnvLenValid = CheckEnvLen(intraPcieEnv.c_str(), MAX_LEN_OF_DIGIT_ENV);
        CHK_PRT_RET(!isEnvLenValid,
            HCCL_ERROR("[Parse][IntraLinkType]errNo[0x%016llx] Invalid INTRA_PCIE_ENABLE env len, len is bigger than "\
                "[%u]. errorno[%d]", HCCL_ERROR_CODE(HCCL_E_PARA), MAX_LEN_OF_DIGIT_ENV, HCCL_E_PARA), HCCL_E_PARA);
        std::string intraPcieStr(intraPcieEnv);
        CHK_RET(GetIntraLinkTypeDigit(intraPcieStr, intraPcie));
    }

    if (intraRoceEnv != "EmptyString") { // 解析HCCL_INTRA_ROCE_ENABLE为数字
        // 校验环境变量长度
        bool isEnvLenValid = CheckEnvLen(intraRoceEnv.c_str(), MAX_LEN_OF_DIGIT_ENV);
        CHK_PRT_RET(!isEnvLenValid,
            HCCL_ERROR("[Parse][IntraLinkType]errNo[0x%016llx] Invalid INTRA_ROCE_ENABLE env len, len is bigger than "\
                "[%u]. errorno[%d]", HCCL_ERROR_CODE(HCCL_E_PARA), MAX_LEN_OF_DIGIT_ENV, HCCL_E_PARA), HCCL_E_PARA);
        std::string intraRoceStr(intraRoceEnv);
        CHK_RET(GetIntraLinkTypeDigit(intraRoceStr, intraRoce));
    }

    // 只配置了roce的环境变量
    if (intraPcieEnv == "EmptyString" && intraRoceEnv != "EmptyString") {
        if (intraRoce == 0) {    // roce环境变量值为0，报错
            HCCL_ERROR("[Parse][IntraLinkType]only set HCCL_INTRA_ROCE_ENABLE, and the val is zero, pls set "\
                "HCCL_INTRA_PCIE_ENABLE");
            return HCCL_E_PARA;
        } else {                 // roce环境变量值为1，走roce
            intraPcie = 0;
        }
        HCCL_RUN_INFO("HCCL_INTRA_PCIE_ENABLE set by environment to [%u], "\
            "HCCL_INTRA_ROCE_ENABLE set by environment to [%u]", intraPcie, intraRoce);
    }

    // 只配置了pcie的环境变量
    if (intraPcieEnv  != "EmptyString" && intraRoceEnv == "EmptyString") {
        if (intraPcie == 0) {   // pcie环境变量值为0，报错
            HCCL_ERROR("[Parse][IntraLinkType]only set HCCL_INTRA_PCIE_ENABLE, and the val is zero, pls set "\
                "HCCL_INTRA_ROCE_ENABLE");
            return HCCL_E_PARA;
        }
        HCCL_RUN_INFO("HCCL_INTRA_PCIE_ENABLE set by environment to [%u], "\
            "HCCL_INTRA_ROCE_ENABLE set by default to [%u]", intraPcie, intraRoce);
    }

    // pcie和roce环境变量同时配置且不相等
    if (intraPcieEnv  != "EmptyString" && intraRoceEnv != "EmptyString") {
        if ((intraPcie == 0 && intraRoce == 1) || (intraPcie == 1 && intraRoce == 0)) {
            HCCL_RUN_INFO("HCCL_INTRA_PCIE_ENABLE set by environment to [%u], "\
                "HCCL_INTRA_ROCE_ENABLE set by environment to [%u]", intraPcie, intraRoce);
        }
    }

    // pcie和roce环境变量同时配置且相等
    if (!(intraPcie ^ intraRoce)) {
        if (intraPcie == 1) {   // 同时为1，暂不支持，报错
            HCCL_ERROR("[Parse][IntraLinkType] Enabling intra Pcie and intra Roce at the same time is not supported now.");
            return HCCL_E_PARA;
        } else {                // 同时为0，走pcie
            HCCL_WARNING("Pcie and Roce Env both set to zero at the same time, intra comm is default Pcie");
            intraPcie = 1;
        }
        HCCL_RUN_INFO("HCCL_INTRA_PCIE_ENABLE set by environment to [%u], "\
            "HCCL_INTRA_ROCE_ENABLE set by environment to [%u]", intraPcie, intraRoce);
    }

    g_externalInput.intraRoceSwitch = intraRoce;
    return HCCL_SUCCESS;
}
HcclResult ParseProfilingConfig()
{
    g_externalInput.profilingMode = false;
    g_externalInput.profilingOption = "";
    std::string profilingEnv = SalGetEnv("PROFILING_MODE");
    CHK_PRT_RET(profilingEnv == "EmptyString",
        HCCL_INFO("environmental variable PROFILING_MODE and GE profiling option is not set, default: false"),
        HCCL_SUCCESS);
    HCCL_DEBUG("PROFILING_MODE[%s] is set", profilingEnv.c_str());
    CHK_PRT_RET(profilingEnv.compare("true") != 0, HCCL_INFO("environmental variable PROFILING_MODE = false"),
        HCCL_SUCCESS);
    g_externalInput.profilingMode = true;
    profilingEnv = SalGetEnv("PROFILING_OPTIONS");
    CHK_PRT_RET(profilingEnv == "EmptyString",
        HCCL_INFO("environmental variable PROFILING_OPTIONS is not set."), HCCL_SUCCESS);

    g_externalInput.profilingOption = profilingEnv;
    HCCL_INFO("Set Env [PROFILING_MODE]: Value[%s]", g_externalInput.profilingOption.c_str());
    return HCCL_SUCCESS;
}

HcclResult ParseHcclWhitelistFilePath()
{
    CHK_PRT_RET((g_externalInput.enableWhitelist != HCCL_WHITELIST_ON), , HCCL_SUCCESS); // 白名单功能无效时无需解析

    std::string filePath = SalGetEnv("HCCL_WHITELIST_FILE");
    if (filePath == "EmptyString") {
        g_externalInput.hcclWhiteListFile.clear();
        HCCL_WARNING("[Parse][HcclWhitelistFilePath]environmental variable HCCL_WHITELIST_DISABLE is [0],"
            "but HCCL_WHITELIST_FILE is not set");
    } else {
        u32 len = strnlen(filePath.c_str(), PATH_MAX);
        if (len == (PATH_MAX) || len == 0) {
            HCCL_ERROR("[Parse][HcclWhitelistFilePath]errNo[0x%016llx] env[HCCL_WHITELIST_FILE] is invalid, "\
                "len is %u", HCCL_ERROR_CODE(HCCL_E_PARA), len);
            return HCCL_E_PARA;
        }
        // 校验文件是否存在
        char realFile[PATH_MAX] = {0};
        if (realpath(filePath.c_str(), realFile) == nullptr) {
            HCCL_RUN_WARNING("[Parse][HcclWhitelistFilePath]path %s is not a valid real path", filePath.c_str());
            g_externalInput.hcclWhiteListFile.clear();
        } else {
            g_externalInput.hcclWhiteListFile = realFile;
        }
        HCCL_RUN_INFO("HCCL_WHITELIST_FILE set by environment to [%s], realpath[%s].", filePath.c_str(), \
            g_externalInput.hcclWhiteListFile.c_str());
    }
    return HCCL_SUCCESS;
}

HcclResult ParseMultiQpSrcPortConfigPath()
{
    std::string filePath = SalGetEnv("HCCL_RDMA_QP_PORT_CONFIG_PATH");
    if (filePath == "EmptyString") {
        g_externalInput.multiQpSrcPortConfigPath.clear();
        HCCL_WARNING("[Parse][MultiQpSrcPortConfigPath]environmental variable HCCL_RDMA_QP_PORT_CONFIG_PATH is empty,"
            "but HCCL_RDMA_QP_PORT_CONFIG_PATH is not set");
    } else {
        u32 len = filePath.size() > PATH_MAX ? PATH_MAX : filePath.size();
        if (len == (PATH_MAX) || len == 0) {
            HCCL_ERROR("[Parse][MultiQpSrcPortConfigPath]errNo[0x%016llx] env[HCCL_RDMA_QP_PORT_CONFIG_PATH] is invalid," \
                "len is %u", HCCL_ERROR_CODE(HCCL_E_PARA), len);
            return HCCL_E_PARA;
        }
        // 校验文件是否存在
        char realFile[PATH_MAX] = {0};
        if (realpath(filePath.c_str(), realFile) == nullptr) {
            HCCL_ERROR("[Parse][MultiQpSrcPortConfigPath]errNo[0x%016llx] path %s is not a valid real path",
                HCOM_ERROR_CODE(HCCL_E_PARA), filePath.c_str());
            return HCCL_E_PARA;
        }
        g_externalInput.multiQpSrcPortConfigPath = realFile;
        HCCL_RUN_INFO("HCCL_RDMA_QP_PORT_CONFIG_PATH set by environment to [%s], realpath[%s]", filePath.c_str(),
            g_externalInput.multiQpSrcPortConfigPath.c_str());
    }
    return HCCL_SUCCESS;
}

HcclResult ParseHcclWhitelistSwitch()
{
    std::string disableWhitelistEnv = SalGetEnv("HCCL_WHITELIST_DISABLE");
    u32 disableWhitelist = 0;

    if (disableWhitelistEnv != "EmptyString") {
        // 校验环境变量长度
        bool isEnvLenValid = CheckEnvLen(disableWhitelistEnv.c_str(), MAX_LEN_OF_DIGIT_ENV);
        CHK_PRT_RET(!isEnvLenValid,
            HCCL_ERROR("[Parse][WhitelistSwitch]errNo[0x%016llx] Invalid HCCL_WHITELIST_DISABLE env len, len is "\
                "bigger than [%u]. errorno[%d]", HCCL_ERROR_CODE(HCCL_E_PARA), MAX_LEN_OF_DIGIT_ENV, HCCL_E_PARA),
            HCCL_E_PARA);
        HcclResult ret = SalStrToULong(disableWhitelistEnv, HCCL_BASE_DECIMAL, disableWhitelist);
        // 若转换出错或使能开关的值不为0和1，报错并设置为默认值
        if (ret != HCCL_SUCCESS || disableWhitelist > 1) {
            HCCL_ERROR("[Parse][WhitelistSwitch]environmental variable HCCL_WHITELIST_DISABLE[%s] is invalid, "\
                "expect[%u ~ %u].", disableWhitelistEnv.c_str(), 0, 1);
            g_externalInput.enableWhitelist = HCCL_WHITELIST_OFF;
            return HCCL_E_PARA;
        }
        HCCL_RUN_INFO("HCCL_WHITELIST_DISABLE set by environment to [%u]", disableWhitelist);
    } else {
        disableWhitelist = 1; // 缺省时关闭白名单
        HCCL_RUN_INFO("HCCL_WHITELIST_DISABLE set by default to [%u]", disableWhitelist);
    }
    g_externalInput.enableWhitelist = !disableWhitelist;
    return HCCL_SUCCESS;
}

HcclResult ParseHcclDeviceNicDisable()
{
    std::string deviceNicConfigEnv = SalGetEnv("HCCL_DEVICE_NIC_DISABLE");
    // 均未设置，默认使能
    if (deviceNicConfigEnv == "EmptyString") {
        HCCL_INFO("HCCL_DEVICE_NIC_DISABLE set by default to [0]");
        return HCCL_SUCCESS;
    }

    u32 deviceNicDisableConfig = 0; // 保存环境变量的解析数字

    // 校验环境变量长度
    bool isEnvLenValid = CheckEnvLen(deviceNicConfigEnv.c_str(), MAX_LEN_OF_DIGIT_ENV);
    CHK_PRT_RET(!isEnvLenValid, HCCL_ERROR("[Parse][DeviceNicDisable]errNo[0x%016llx] Invalid" \
        " HCCL_DEVICE_NIC_DISABLE env len, len is bigger than [%u]. errorno[%d]",
        HCCL_ERROR_CODE(HCCL_E_PARA), MAX_LEN_OF_DIGIT_ENV, HCCL_E_PARA), HCCL_E_PARA);
    CHK_RET(IsAllDigit(deviceNicConfigEnv.c_str()));
    CHK_RET(SalStrToULong(deviceNicConfigEnv.c_str(), HCCL_BASE_DECIMAL, deviceNicDisableConfig));

    if ((deviceNicDisableConfig != 0) && (deviceNicDisableConfig != 1)) { // 判断转换后的数字是否为0或1
        HCCL_ERROR("[Get][GetDeviceNicDisableDigit]environmental digit variable error, DeviceNicDisableDig[%u]",
            deviceNicDisableConfig);
        return HCCL_E_PARA;
    }
    // 资料未公开的环境变量，不能通过默认日志级别输出，调整为info级别
    HCCL_INFO("HCCL_DEVICE_NIC_DISABLE set by environment to [%u]", deviceNicDisableConfig);
    g_externalInput.hcclDeviceNicDisable = (deviceNicDisableConfig == 1);
    return HCCL_SUCCESS;
}

HcclResult ParseHcclHostRdmaEnable()
{
    std::string hostRdmaConfigEnv = SalGetEnv("HCCL_HOST_RDMA_ENABLE");
    // 均未设置，默认使能
    if (hostRdmaConfigEnv == "EmptyString") {
        HCCL_INFO("HCCL_HOST_RDMA_ENABLE set by default to [0]");
        return HCCL_SUCCESS;
    }

    u32 hostRdmaEnableConfig = 0; // 保存环境变量的解析数字

    // 校验环境变量长度
    bool isEnvLenValid = CheckEnvLen(hostRdmaConfigEnv.c_str(), MAX_LEN_OF_DIGIT_ENV);
    CHK_PRT_RET(!isEnvLenValid, HCCL_ERROR("[Parse][HostRdmaEnable]errNo[0x%016llx] Invalid" \
        " HCCL_HOST_RDMA_ENABLE env len, len is bigger than [%u]. errorno[%d]",
        HCCL_ERROR_CODE(HCCL_E_PARA), MAX_LEN_OF_DIGIT_ENV, HCCL_E_PARA), HCCL_E_PARA);
    CHK_RET(IsAllDigit(hostRdmaConfigEnv.c_str()));
    CHK_RET(SalStrToULong(hostRdmaConfigEnv.c_str(), HCCL_BASE_DECIMAL, hostRdmaEnableConfig));

    if ((hostRdmaEnableConfig != 0) && (hostRdmaEnableConfig != 1)) { // 判断转换后的数字是否为0或1
        HCCL_ERROR("[Get][GetHostRdmaEnableDigit]environmental digit variable error, HostRdmaEnableDig[%u]",
            hostRdmaEnableConfig);
        return HCCL_E_PARA;
    }
    // 资料未公开的环境变量，不能通过默认日志级别输出，调整为info级别
    HCCL_INFO("HCCL_HOST_RDMA_ENABLE set by environment to [%u]", hostRdmaEnableConfig);
    g_externalInput.hcclHostRdmaEnable = (hostRdmaEnableConfig == 1);
    return HCCL_SUCCESS;
}

HcclResult ParseHcclIfBasePort()
{
    std::string ifBasePort = SalGetEnv("HCCL_IF_BASE_PORT");
    u32 basePort = HCCL_INVALID_PORT;

    if (ifBasePort != "EmptyString") {
        // 校验环境变量长度
        bool isEnvLenValid = CheckEnvLen(ifBasePort.c_str(), MAX_LEN_OF_DIGIT_ENV);
        CHK_PRT_RET(!isEnvLenValid,
            HCCL_ERROR("[Parse][HcclIfBasePort]errNo[0x%016llx] Invalid HcclIfBasePort env len, len is bigger than "\
                "[%u]. errorno[%d]", HCCL_ERROR_CODE(HCCL_E_PARA), MAX_LEN_OF_DIGIT_ENV, HCCL_E_PARA), HCCL_E_PARA);

        CHK_RET(IsAllDigit(ifBasePort.c_str()));
        HcclResult ret = SalStrToULong(ifBasePort, HCCL_BASE_DECIMAL, basePort);
        // 若数字小于1024或者数字大于65520，报错并设置为默认值HOST_CONTROL_BASE_PORT
        if (ret != HCCL_SUCCESS || basePort > HOST_PORT_MAX || basePort < HCCL_BASE_PORT_MIN) {
            HCCL_ERROR("[Parse][HcclIfBasePort]environmental variable HCCL_IF_BASE_PORT error, errNo[0x%016llx]" \
                "ifBasePort[%s] portRange[%u,%u]",
                HCOM_ERROR_CODE(ret), ifBasePort.c_str(), HCCL_BASE_PORT_MIN, HOST_PORT_MAX);
            return HCCL_E_PARA;
        }
        HCCL_RUN_INFO("HCCL_IF_BASE_PORT set by environment to [%u]", basePort);
    } else {
        HCCL_RUN_INFO("HCCL_IF_BASE_PORT set by default to [%u]", HOST_CONTROL_BASE_PORT);
    }
    g_externalInput.hcclIfBasePort = basePort;
    return HCCL_SUCCESS;
}

HcclResult ParseHcclIfIp()
{
    std::string hcclControlIfIp  = SalGetEnv("HCCL_IF_IP");
    if (hcclControlIfIp != "EmptyString") {
        CHK_PRT_RET(g_externalInput.hcclControlIfIp.SetReadableAddress(hcclControlIfIp),
            HCCL_ERROR("[Parse][HcclIfIp]IP address[%s] is invalid.", hcclControlIfIp.c_str()), HCCL_E_PARA);
        HCCL_RUN_INFO("HCCL_IF_IP is set to [%s], ip[%s].", hcclControlIfIp.c_str(),
            g_externalInput.hcclControlIfIp.GetReadableAddress());
    } else {
        HCCL_RUN_INFO("HCCL_IF_IP is not set");
    }
    return HCCL_SUCCESS;
}

HcclResult ParseHcclSocketFamily()
{
    std::string hcclSocketFamily = SalGetEnv("HCCL_SOCKET_FAMILY");
    if (hcclSocketFamily != "EmptyString") {
        HCCL_RUN_INFO("HCCL_SOCKET_FAMILY set by environment to [%s]", hcclSocketFamily.c_str());
        if (hcclSocketFamily == "AF_INET") {
            g_externalInput.hcclSocketFamily = AF_INET;
        } else if (hcclSocketFamily == "AF_INET6") {
            g_externalInput.hcclSocketFamily = AF_INET6;
        } else {
            g_externalInput.hcclSocketFamily = -1;
            HCCL_ERROR("[Parse][HcclSocketFamily]environmental variable HCCL_SOCKET_FAMILY[%s] is invalid. it should "
                       "be \"AF_INET\" or \"AF_INET6\".",
                hcclSocketFamily.c_str());
            return HCCL_E_PARA;
        }
    } else {
        g_externalInput.hcclSocketFamily = -1;
        HCCL_RUN_INFO("HCCL_SOCKET_FAMILY is not set and is used by default [AF_INET]");
    }
    return HCCL_SUCCESS;
}

HcclResult ParseHcclSocketIfName()
{
    bool searchNot = false;
    bool searchExact = false;
    std::string hcclSocketIfName = SalGetEnv("HCCL_SOCKET_IFNAME");
    std::string remainSocketIfName = hcclSocketIfName;
    g_externalInput.hcclSocketIfName.configIfNames.clear();

    if (hcclSocketIfName != "EmptyString") {
        // 获取HCCL_SOCKET_IFNAME环境变量匹配规则
        if (!hcclSocketIfName.empty() && hcclSocketIfName.at(0) == '^') {
            searchNot = true;
            // 获取从1位置开始剩余部分环境变量内容
            remainSocketIfName = hcclSocketIfName.substr(1);
        }

        if (!remainSocketIfName.empty() && remainSocketIfName.at(0) == '=') {
            searchExact = true;
            remainSocketIfName = remainSocketIfName.substr(1);
        }

        // 获取用户输入的网卡名列表(使用逗号隔开),将网卡名列表存放到全局vector变量中
        HcclResult ret = SplitHcclSocketIfName(remainSocketIfName, g_externalInput.hcclSocketIfName.configIfNames);
        CHK_PRT_RET(ret != HCCL_SUCCESS,
            HCCL_ERROR("[Parse][HcclSocketIfName]hccl IfName config[%s] is invalid.", hcclSocketIfName.c_str()),
            HCCL_E_PARA);
        HCCL_RUN_INFO("HCCL_SOCKET_IFNAME set by environment to [%s]", hcclSocketIfName.c_str());
    } else {
        HCCL_RUN_INFO("HCCL_SOCKET_IFNAME set by default to [%s]", hcclSocketIfName.c_str());
    }
    g_externalInput.hcclSocketIfName.searchNot = searchNot;
    g_externalInput.hcclSocketIfName.searchExact = searchExact;
    return HCCL_SUCCESS;
}

HcclResult ParseSendCqDepth()
{
    g_externalInput.hcclSendCqDepth = HCCL_SEND_CQ_DEPTH_DEFAULT;
    std::string hcclSendCqDepthEnv = SalGetEnv("HCCL_SEND_CQ_DEPTH");
    if (hcclSendCqDepthEnv == "EmptyString") {
        HCCL_INFO("HCCL_SEND_CQ_DEPTH set by default to [%u]", g_externalInput.hcclSendCqDepth);
        return HCCL_SUCCESS;
    }

    s32 sendCqDepth = 0;
    CHK_RET(IsAllDigit(hcclSendCqDepthEnv.c_str()));
    HcclResult ret = SalStrToInt(hcclSendCqDepthEnv.c_str(), HCCL_BASE_DECIMAL, sendCqDepth);
    if (ret != HCCL_SUCCESS || sendCqDepth < HCCL_SEND_CQ_DEPTH_MINNUM || sendCqDepth > HCCL_SEND_CQ_DEPTH_MAXNUM) {
        HCCL_ERROR("[Parse][SendCqDepthEnv]environmental variable HCCL_SEND_CQ_DEPTH error,"
            "errNo[0x%016llx] sendCqDepth[%s]", HCOM_ERROR_CODE(ret), hcclSendCqDepthEnv.c_str());
        g_externalInput.hcclSendCqDepth = HCCL_SEND_CQ_DEPTH_DEFAULT;
        return HCCL_E_PARA;
    }

    g_externalInput.hcclSendCqDepth = sendCqDepth;
    // 资料未公开的环境变量，不能通过默认日志级别输出，调整为info级别
    HCCL_INFO("HCCL_SEND_CQ_DEPTH set by environment to [%u].", g_externalInput.hcclSendCqDepth);
    return HCCL_SUCCESS;
}

HcclResult ParseDFTPrintLevel()
{
    g_externalInput.hcclDftEnable = true;
    std::string enableEntryLogEnv = SalGetEnv("HCCL_DFT");
    if (enableEntryLogEnv == "EmptyString") {
        HCCL_INFO("HCCL_DFT is not set, default value is %u.", g_externalInput.hcclDftEnable);
        return HCCL_SUCCESS;
    }

    if (enableEntryLogEnv == "OP_TRACE:1") {
        g_externalInput.hcclDftEnable = true;
    } else if (enableEntryLogEnv == "OP_TRACE:0") {
        g_externalInput.hcclDftEnable = false;
    } else {
        HCCL_ERROR("[ParseDFTPrintLevel]HCCL_DFT is invalid.");
        return HCCL_E_PARA;
    }
    // 资料未公开的环境变量，不能通过默认日志级别输出，调整为info级别
    HCCL_INFO("HCCL_DFT set by environment OP_TRACE[%u].", g_externalInput.hcclDftEnable);
    return HCCL_SUCCESS;
}

HcclResult SplitHcclSocketIfName(const std::string &socketIfName, std::vector<std::string> &configIfNames)
{
    std::string remainSocketIfName;
    std::size_t found = socketIfName.find(",");
    if ((found == 0) || (found == (socketIfName.length() - 1))) {
        HCCL_ERROR("[Split][HcclSocketIfName] configIfNames config is invalid.");
        return HCCL_E_PARA;
    } else if (found != std::string::npos) {
        remainSocketIfName = socketIfName.substr(found + 1);
    } else {
        // 最后一组配置,剩余的字符串为空
    }
    configIfNames.push_back(socketIfName.substr(0, found));

    if (!remainSocketIfName.empty()) {
        CHK_RET(SplitHcclSocketIfName(remainSocketIfName, configIfNames));
    }

    return HCCL_SUCCESS;
}

HcclResult SplitHcclOpType(const std::string &algoConfig, std::vector<std::string> &algos)
{
    std::string remainAlgoConfig;
    std::size_t found = algoConfig.find("/");
    if ((found == 0) || (found == (algoConfig.length() - 1))) {
        HCCL_ERROR("[Split][SplitHcclOpType] algo config is invalid.");
        return HCCL_E_PARA;
    } else if (found != std::string::npos) {
        remainAlgoConfig = algoConfig.substr(found + 1);
    }
    algos.push_back(algoConfig.substr(0, found));
    if (!remainAlgoConfig.empty()) {
        CHK_RET(SplitHcclOpType(remainAlgoConfig, algos));
    }
    return HCCL_SUCCESS;
}

// 新的逐算法的配置和原有的统一配置只可使用一种，发现同时存在时报错
HcclResult CheckAlgoConfigValid(
    std::vector<std::string> &algos,
    bool& anyCommonConfig,
    bool& anySpecificConfig)
{
    for (std::string& algConfig : algos) {
        std::size_t found = algConfig.find("=");
        if ((found == 0) || (found == (algConfig.length() - 1))) {
            HCCL_ERROR("[Split][CheckAlgoConfigValid] algo config is invalid.");
            return HCCL_E_PARA;
        } else if (found != std::string::npos) {
            anySpecificConfig = true;
        } else {
            anyCommonConfig = true;
        }
    }
    if (anyCommonConfig && anySpecificConfig) {
        HCCL_ERROR("[CheckAlgoConfigValid]should not set both algo config way");
        return HCCL_E_PARA;
    }
    if (anyCommonConfig && algos.size() > 1) {
        HCCL_ERROR("[CheckAlgoConfigValid]should only set one common config");
        return HCCL_E_PARA;
    }
    return HCCL_SUCCESS;
}

HcclResult ParseAlgoString(std::string opName, std::string &algoString, std::vector<HcclAlgoType>& algType)
{
    algType = std::vector<HcclAlgoType>(HCCL_ALGO_LEVEL_NUM, HcclAlgoType::HCCL_ALGO_TYPE_DEFAULT);
    std::vector<std::string> algoLevels;
    HcclResult ret = SplitHcclAlgoLevel(algoString, algoLevels);
    CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[Set][HcclAlgoConfig]hccl algo config[%s] is invalid. "\
        "expect: level0:NA;level1:<algo> or <op0>=level0:NA;level1:<algo0>/<op1>=level0:NA;level1:<algo1>",
        algoString.c_str()), ret);
    for (auto algoLevel : algoLevels) {
        u32 level = 0;
        HcclAlgoType algo = HcclAlgoType::HCCL_ALGO_TYPE_DEFAULT;
        ret = ParserHcclAlgoLevel(algoLevel, level, algo);
        CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("[Set][HcclAlgoConfig]hccl algo config[%s] is invalid. "\
            "expect: level0:NA;level1:<algo> or <op0>=level0:NA;level1:<algo0>/<op1>=level0:NA;level1:<algo1>",
            algoString.c_str()), ret);
        // 检查是否存在重复配置level
        if (algType[level] != HcclAlgoType::HCCL_ALGO_TYPE_DEFAULT) {
            HCCL_ERROR("[Set][HcclAlgoConfig]hccl algo config[%s] is invalid. "\
                "expect: level0:NA;level1:<algo> or <op0>=level0:NA;level1:<algo0>/<op1>=level0:NA;level1:<algo1>",
                algoString.c_str());
            return HCCL_E_PARA;
        }
        algType[level] = algo;
    }
    auto level0Iter = HcclAlgoTypeMap.find(algType[HCCL_ALGO_LEVEL_0]);
    auto level1Iter = HcclAlgoTypeMap.find(algType[HCCL_ALGO_LEVEL_1]);
    auto level2Iter = HcclAlgoTypeMap.find(algType[HCCL_ALGO_LEVEL_2]);
    auto level3Iter = HcclAlgoTypeMap.find(algType[HCCL_ALGO_LEVEL_3]);
    HCCL_RUN_INFO("hccl algo op %s config: config level0:%s, level1:%s, level2:%s, level3:%s",
        opName.c_str(),
        level0Iter->second.c_str(), level1Iter->second.c_str(),
        level2Iter->second.c_str(), level3Iter->second.c_str());
    return HCCL_SUCCESS;
}

HcclResult SetCommonAlgType(std::vector<std::string> &algos)
{
    std::vector<HcclAlgoType> algType;
    CHK_RET(ParseAlgoString("all op type", algos[0], algType));
    for (u32 opType = 0; opType < static_cast<u32>(HcclCMDType::HCCL_CMD_MAX); opType++) {
        g_externalInput.hcclAlgoConfig[static_cast<HcclCMDType>(opType)] = algType;
    }
    return HCCL_SUCCESS;
}

HcclResult SetSpecificAlgType(std::vector<std::string> &algos)
{
    for (std::string& algConfig : algos) {
        std::size_t found = algConfig.find("=");
        std::string opStringName = algConfig.substr(0, found);
        if (opStringName == "others") {
            std::vector<HcclAlgoType> algType;
            std::string remainAlgoConfig = algConfig.substr(found + 1);
            CHK_RET(ParseAlgoString("others op type", remainAlgoConfig, algType));
            for (u32 opType = 0; opType < static_cast<u32>(HcclCMDType::HCCL_CMD_MAX); opType++) {
                g_externalInput.hcclAlgoConfig[static_cast<HcclCMDType>(opType)] = algType;
            }
        }
    }
    std::map<std::string, HcclCMDType> hcclOpTypeMap = {
        {"broadcast", HcclCMDType::HCCL_CMD_BROADCAST},
        {"allreduce", HcclCMDType::HCCL_CMD_ALLREDUCE},
        {"reduce", HcclCMDType::HCCL_CMD_REDUCE},
        {"send", HcclCMDType::HCCL_CMD_SEND},
        {"receive", HcclCMDType::HCCL_CMD_RECEIVE},
        {"allgather", HcclCMDType::HCCL_CMD_ALLGATHER},
        {"reducescatter", HcclCMDType::HCCL_CMD_REDUCE_SCATTER},
        {"alltoall", HcclCMDType::HCCL_CMD_ALLTOALL},
        {"gather", HcclCMDType::HCCL_CMD_GATHER},
        {"scatter", HcclCMDType::HCCL_CMD_SCATTER},
        {"sendrecv", HcclCMDType::HCCL_CMD_BATCH_SEND_RECV},
    };
    for (std::string& algConfig : algos) {
        std::size_t found = algConfig.find("=");
        std::string opStringName = algConfig.substr(0, found);
        if (hcclOpTypeMap.find(opStringName) != hcclOpTypeMap.end()) {
            HcclCMDType optype = hcclOpTypeMap[opStringName];
            std::string remainAlgoConfig = algConfig.substr(found + 1);
            std::vector<HcclAlgoType> algType;
            CHK_RET(ParseAlgoString(opStringName, remainAlgoConfig, algType));
            if (algType[0] == HcclAlgoType::HCCL_ALGO_TYPE_NULL) {
                HCCL_ERROR("[SetSpecificAlgType] specific config level0 not support null type.");
                return HCCL_E_PARA;
            }
            g_externalInput.hcclAlgoConfig[optype] = algType;
        } else {
            HCCL_ERROR("[SetSpecificAlgType] specific config optype[%s] is invalid, please check",
                opStringName.c_str());
            return HCCL_E_PARA;
        }
    }
    g_externalInput.hcclAlgoConfig[HcclCMDType::HCCL_CMD_ALLTOALLV] =
        g_externalInput.hcclAlgoConfig[HcclCMDType::HCCL_CMD_ALLTOALL];
    g_externalInput.hcclAlgoConfig[HcclCMDType::HCCL_CMD_ALLTOALLVC] =
        g_externalInput.hcclAlgoConfig[HcclCMDType::HCCL_CMD_ALLTOALL];
    return HCCL_SUCCESS;
}

HcclResult SetHcclAlgoConfig(const std::string &hcclAlgo)
{
    std::string algoConfig = hcclAlgo;
    algoConfig.erase(std::remove(algoConfig.begin(), algoConfig.end(), ' '), algoConfig.end());
    if (algoConfig.empty()) {
        HCCL_RUN_INFO("hccl algo config is empty, HCCL use built-in algo selection.");
        return HCCL_SUCCESS;
    }
    std::vector<std::string> algoPerOptype;
    CHK_RET(SplitHcclOpType(algoConfig, algoPerOptype));
    bool anyCommonConfig = false;
    bool anySpecificConfig = false;
    CHK_RET(CheckAlgoConfigValid(algoPerOptype, anyCommonConfig, anySpecificConfig));
    if (anyCommonConfig) {
        CHK_RET(SetCommonAlgType(algoPerOptype));
    } else {
        g_externalInput.specificAlgoMode = anySpecificConfig;
        CHK_RET(SetSpecificAlgType(algoPerOptype));
    }
    return HCCL_SUCCESS;
}

HcclResult SetHccLExecTimeOut(const char *execTimeOutStr, const HcclExecTimeoutSet execTimeOutSet)
{
    CHK_PTR_NULL(execTimeOutStr);
    DevType deviceType;
    CHK_RET(hrtGetDeviceType(deviceType)); // 910A和910B要分开
    s32 hcclExecTimeout = (deviceType == DevType::DEV_TYPE_910_93 || deviceType == DevType::DEV_TYPE_910B) ?\
        HCCL_EXEC_TIME_OUT_S_910_93 : HCCL_EXEC_TIME_OUT_S;
    s32 execTimeOut = hcclExecTimeout;
    g_externalInput.execTimeOut = hcclExecTimeout;
    CHK_RET(IsAllDigit(execTimeOutStr));
    HcclResult ret = SalStrToInt(execTimeOutStr, HCCL_BASE_DECIMAL, execTimeOut);

    bool flag = false;
    if (deviceType == DevType::DEV_TYPE_910_93 || deviceType == DevType::DEV_TYPE_910B) {
        // 910B和910_93算子超时时间范围0s-2147483647s,其中0代表永不超时
        flag = (ret !=  HCCL_SUCCESS || (execTimeOut < 0) || (execTimeOut > HCCL_EXEC_TIME_OUT_S_910_93));
        RPT_ENV_ERR(flag,
            "EI0001",
            std::vector<std::string>({ "env", "tips" }),\
            std::vector<std::string>({
                "HCCL_EXEC_TIMEOUT", "it should be a number greater than or equal to 0s and less "\
                "than or equal to 2147483647s"
            }));
        CHK_PRT_RET(flag,
            HCCL_ERROR("[Parse][HcclExecTimeOut]ExecTimeOut[%s] is invalid. except: [0, %d]",
            execTimeOutStr, HCCL_EXEC_TIME_OUT_S_910_93), HCCL_E_PARA);
    } else {
        // 非910B和910_93算子超时时间范围1s-17340s
        flag = (ret !=  HCCL_SUCCESS || (execTimeOut <= 0) || (execTimeOut > HCCL_EXEC_TIME_OUT_S));
        RPT_ENV_ERR(flag,
            "EI0001",
            std::vector<std::string>({ "env", "tips" }),\
            std::vector<std::string>({
            "HCCL_EXEC_TIMEOUT", "it should be a number greater than or equal to 1s and less than or equal to 17340s"
            }));
        CHK_PRT_RET(flag,
            HCCL_ERROR("[Parse][HcclExecTimeOut]ExecTimeOut[%s] is invalid. except: [1, %d]",
            execTimeOutStr, HCCL_EXEC_TIME_OUT_S), HCCL_E_PARA);
        s32 intPart = execTimeOut / HCCL_INTEVAL_EXEC_TIME_OUT_S;
        intPart = (intPart == 0) ? 1 : intPart;
        execTimeOut = intPart * HCCL_INTEVAL_EXEC_TIME_OUT_S;
    }
    g_externalInput.execTimeOut = execTimeOut;
    g_externalInput.execTimeOutSet = execTimeOutSet;
    if (execTimeOutSet == HcclExecTimeoutSet::HCCL_EXEC_TIMEOUT_SET_BY_ENV) {
        HCCL_RUN_INFO("HCCL_EXEC_TIMEOUT set by environment to [%d]s", execTimeOut);
    } else {
        HCCL_RUN_INFO("HCCL_EXEC_TIMEOUT set by GE option to [%d]s", execTimeOut);
    }
    return HCCL_SUCCESS;
}

HcclResult SplitHcclAlgoLevel(const std::string &algoConfig, std::vector<std::string> &algos)
{
    std::string remainAlgoConfig;
    std::size_t found = algoConfig.find(";");
    if ((found == 0) || (found == (algoConfig.length() - 1))) {
        HCCL_ERROR("[Split][HcclAlgoLevel] algo config is invalid.");
        return HCCL_E_PARA;
    } else if (found != std::string::npos) {
        remainAlgoConfig = algoConfig.substr(found + 1);
    } else {
        // 最后一组配置,剩余的字符串为空
    }
    algos.push_back(algoConfig.substr(0, found));

    if (algos.size() > HCCL_ALGO_LEVEL_NUM) {
        HCCL_ERROR("[Split][HcclAlgoLevel] algo config is invalid. algo level is more than %u.", HCCL_ALGO_LEVEL_NUM);
        return HCCL_E_PARA;
    }
    if (!remainAlgoConfig.empty()) {
        CHK_RET(SplitHcclAlgoLevel(remainAlgoConfig, algos));
    }

    return HCCL_SUCCESS;
}

HcclResult ParserHcclAlgoLevel(const std::string &algoLevel, u32 &level, HcclAlgoType &algoType)
{
    std::size_t found = algoLevel.find(":");
    if ((found == 0) || (found == (algoLevel.length() - 1))) {
        HCCL_ERROR("[Parser][HcclAlgoLevel] algo config is invalid.");
        return HCCL_E_PARA;
    }

    std::string orginalLevel = algoLevel.substr(0, found);
    std::string orginalAlgo = algoLevel.substr(found + 1);

    const std::map<std::string, u32> hcclAlgoLevelMap = {
        {"level0", HCCL_ALGO_LEVEL_0},
        {"level1", HCCL_ALGO_LEVEL_1},
        {"level2", HCCL_ALGO_LEVEL_2},
        {"level3", HCCL_ALGO_LEVEL_3}
    };

    const std::map<std::string, HcclAlgoType> hcclAlgoTypeMap = {
        {"null", HcclAlgoType::HCCL_ALGO_TYPE_NULL},
        {"ring", HcclAlgoType::HCCL_ALGO_TYPE_RING},
        {"pipeline", HcclAlgoType::HCCL_ALGO_TYPE_PIPELINE},
        {"fullmesh", HcclAlgoType::HCCL_ALGO_TYPE_FULLMESH},
        {"H-D_R", HcclAlgoType::HCCL_ALGO_TYPE_HDR},
        {"pairwise", HcclAlgoType::HCCL_ALGO_TYPE_PAIRWISE},
        {"NHR", HcclAlgoType::HCCL_ALGO_TYPE_NHR},
        {"NHR_V1", HcclAlgoType::HCCL_ALGO_TYPE_NHR_V1},
        {"AHC", HcclAlgoType::HCCL_ALGO_TYPE_AHC},
        {"AHC_BROKE", HcclAlgoType::HCCL_ALGO_TYPE_AHC_BROKE},
        {"NB", HcclAlgoType::HCCL_ALGO_TYPE_NB},
        {"NA", HcclAlgoType::HCCL_ALGO_TYPE_NA},
    };

    auto iterAlgoLevel = hcclAlgoLevelMap.find(orginalLevel);
    if (iterAlgoLevel == hcclAlgoLevelMap.end()) {
        HCCL_ERROR("[Parser][HcclAlgoLevel] algo config is invalid, level %s is not supported.", orginalLevel.c_str());
        return HCCL_E_PARA;
    }

    auto iterAlgoType = hcclAlgoTypeMap.find(orginalAlgo);
    if (iterAlgoType == hcclAlgoTypeMap.end()) {
        HCCL_ERROR("[Parser][HcclAlgoLevel] algo config is invalid, algo %s is not supported.", orginalAlgo.c_str());
        return HCCL_E_PARA;
    }

    level = iterAlgoLevel->second;
    algoType = iterAlgoType->second;

    return HCCL_SUCCESS;
}

bool CheckEnvLen(const char *envStr, u32 envMaxLen)
{
    // 校验环境变量长度
    u32 envLen = strnlen(envStr, envMaxLen + 1);
    if (envLen == (envMaxLen + 1)) {
        HCCL_ERROR("[Check][EnvLen]errNo[0x%016llx] env len is invalid, len is %u", HCCL_ERROR_CODE(HCCL_E_PARA),
            envLen);
        return false;
    }
    return true;
}
HcclResult SetMasterInfo(const string &masterIp, const string &masterPort, const string & masterDeviceId,
    const string &rankSize, const string &rankIp)
{
    HcclResult ret = HCCL_SUCCESS;
    ret = g_externalInput.masterInfo.serverIp.SetReadableAddress(masterIp);
    if (ret != HCCL_SUCCESS) {
        HCCL_ERROR("[Parse][MasterInfo]masterIp address[CM_CHIEF_IP][%s] is invalid.", masterIp.c_str());
        RPT_ENV_ERR(ret, "EI0001", std::vector<std::string>({"env","tips"}),\
            std::vector<std::string>({"CM_CHIEF_IP", "it should be an available ip."}));
        return HCCL_E_PARA;
    }

    ret = IsAllDigit(masterPort.c_str());
    ret = (ret == HCCL_SUCCESS) ? SalStrToULong(masterPort, HCCL_BASE_DECIMAL, g_externalInput.masterInfo.port) : ret;
    if (ret != HCCL_SUCCESS || g_externalInput.masterInfo.port > HOST_PORT_MAX) {
        HCCL_ERROR("[Parse][HcclMasterInfo] option masterPort[CM_CHIEF_PORT] error, errNo[0x%016llx] masterPort[%s] " \
            "portRange[%u,%u]", HCOM_ERROR_CODE(ret), masterPort.c_str(), PORT_MIN, HOST_PORT_MAX);
        RPT_ENV_ERR(HCCL_E_PARA, "EI0001", std::vector<std::string>({ "env", "tips" }),
            std::vector<std::string>({"CM_CHIEF_PORT", "it should be a unsigned number less than the max port num"}));
            return HCCL_E_PARA;
    }

    ret = IsAllDigit(masterDeviceId.c_str());
    ret = (ret == HCCL_SUCCESS) ?
        SalStrToULong(masterDeviceId, HCCL_BASE_DECIMAL, g_externalInput.masterInfo.serverDeviceId) : ret;
    if (ret != HCCL_SUCCESS || g_externalInput.masterInfo.serverDeviceId >= MAX_MODULE_DEVICE_NUM) {
        HCCL_ERROR("[Parse][HcclMasterInfo]option master device id[CM_CHIEF_DEVICE] error, errNo[0x%016llx] "
            "masterDeviceId[%s]", HCOM_ERROR_CODE(ret), masterDeviceId.c_str());
        RPT_ENV_ERR(HCCL_E_PARA, "EI0001", std::vector<std::string>({ "env", "tips" }),
            std::vector<std::string>({"CM_CHIEF_DEVICE",
                "it should be a unsigned number less than the max device num"}));
            return HCCL_E_PARA;
    }

    if (rankIp.size() == 0) {
        g_externalInput.masterInfo.agentIp.clear();
    } else {
        ret = g_externalInput.masterInfo.agentIp.SetReadableAddress(rankIp);
        if (ret != HCCL_SUCCESS) {
            HCCL_ERROR("[Parse][MasterInfo]masterIp agent address[CM_WORKER_IP][%s] is invalid.", rankIp.c_str());
            RPT_ENV_ERR(HCCL_E_PARA, "EI0001", std::vector<std::string>({"env","tips"}),\
                std::vector<std::string>({"CM_WORKER_IP", "it should be an available ip."}));
            return HCCL_E_PARA;
        }
    }

    ret = IsAllDigit(rankSize.c_str());
    ret = (ret == HCCL_SUCCESS) ? SalStrToULong(rankSize, HCCL_BASE_DECIMAL, g_externalInput.masterInfo.rankSize) : ret;
    if (ret != HCCL_SUCCESS) {
        HCCL_ERROR("[Parse][HcclMasterInfo] option rankSize[CM_WORKER_SIZE] error, errNo[0x%016llx] rankSize[%s]",
            HCOM_ERROR_CODE(ret), rankSize.c_str());
        return HCCL_E_PARA;
    }
    return HCCL_SUCCESS;
}
HcclResult SetTcpMode(const bool isTcpMode)
{
    g_externalInput.isTcpMode = isTcpMode;
    return HCCL_SUCCESS;
}

HcclResult SetEsMaxPsTable(const u32 esMaxPsTable)
{
    g_externalInput.esMaxPsTable = esMaxPsTable;
    return HCCL_SUCCESS;
}

u32 GetEsMaxPsTable()
{
    return g_externalInput.esMaxPsTable;
}

HcclResult SetEsStreamNum(const u32 streamNum)
{
    g_externalInput.streamNum = streamNum;
    return HCCL_SUCCESS;
}

u32 GetEsStreamNum()
{
    return g_externalInput.streamNum;
}

HcclResult SetDeterministic(bool isDeterministic)
{
    g_externalInput.hcclDeterministic = isDeterministic;
    return HCCL_SUCCESS;
}

void SetDumpDebugMode(const bool dumpDebug)
{
    g_externalInput.dumpDebug = dumpDebug;
    return;
}

HcclResult SetFftsSwitch(const bool switchStatus)
{
    g_externalInput.enableFfts = switchStatus;
    return HCCL_SUCCESS;
}

HcclResult SetRdmaSdmaConcurrentDisable() {
    g_externalInput.enableRdmaSdmaConcurrent = false;
    return HCCL_SUCCESS;
}

HcclResult ParseNpuNetProtocol(const string &npuNetProtocol)
{
    u32 len = strnlen(npuNetProtocol.c_str(), NPU_NET_PROTOCOL_MAX_LEN);
    if (len == NPU_NET_PROTOCOL_MAX_LEN) {
        HCCL_ERROR("[ParseNpuNetProtocol]errNo[0x%016llx] env[HCCL_NPU_NET_PROTOCOL] is invalid, "\
            "len is %u", HCCL_ERROR_CODE(HCCL_E_PARA), len);
        return HCCL_E_PARA;
    }
    if (len == 0) {
        HCCL_INFO("HCCL_NPU_NET_PROTOCOL len is 0, RDMA is used by default.");
        g_externalInput.protocolType = ProtocolType::RDMA;
        return HCCL_SUCCESS;
    }

    if (npuNetProtocol == "TCP") {
        g_externalInput.protocolType = ProtocolType::TCP;
    } else if (npuNetProtocol == "RDMA") {
        g_externalInput.protocolType = ProtocolType::RDMA;
    } else {
        HCCL_ERROR("The pattern format is error. protocol should be TCP or RDMA.");
        return HCCL_E_PARA;
    }
    HCCL_INFO("protocol[%s] SetProtocolType is %u", npuNetProtocol.c_str(), g_externalInput.protocolType);
    return HCCL_SUCCESS;
}

HcclResult ParseResourceFileProtocol()
{
    nlohmann::json fileContent;
    std::string protocolStr;
    char realFile[PATH_MAX] = {0};

    const std::string getConfig = SalGetEnv("HELPER_RES_CONFIG");
    const std::string getFilePath = SalGetEnv("HELPER_RES_FILE_PATH");
    if (getConfig != "EmptyString") {
        HCCL_INFO("environmental variable HELPER_RES_CONFIG = [%s] ", getConfig.c_str());
        CHK_RET(SalParseInformation(fileContent, getConfig));
    } else if (getFilePath != "EmptyString") {
        HCCL_INFO("environmental variable HELPER_RES_FILE_PATH = [%s] ", getFilePath.c_str());
        std::string getFilePathStr = getFilePath;
        if (getFilePathStr[getFilePathStr.length() - 1] != '/') {
            getFilePathStr = getFilePathStr + "/resource.json";
        } else {
            getFilePathStr = getFilePathStr + "resource.json";
        }
        CHK_RET(LoadJsonFile(getFilePathStr, fileContent));
    } else {
        std::string defaultPath = "/usr/local/Ascend/latest/conf/resource.json";
        HCCL_WARNING("can't find HELPER_RES_CONFIG or HELPER_RES_FILE_PATH, get protocol type from default path [%s]",
            defaultPath.c_str());
        if (realpath(defaultPath.c_str(), realFile) == nullptr) {
            HCCL_INFO("default resource file is not exist.RDMA is used by default.");
            // 判断对端形态
            g_externalInput.remoteIsHdc = true;
            g_externalInput.protocolType = ProtocolType::RDMA;
            return HCCL_SUCCESS;
        }
        HcclResult ret = LoadJsonFile(defaultPath, fileContent);
        CHK_PRT_RET(ret != HCCL_SUCCESS, HCCL_ERROR("load json file from default path [%s] failed.",
            defaultPath.c_str()), HCCL_E_PARA);
    }

    if (fileContent.find("protocol") != fileContent.end()) {
        CHK_RET(SalGetJsonProperty(fileContent, "protocol", protocolStr));
    } else {
        protocolStr = "RDMA";
    }
    HCCL_INFO("protocol is %s .", protocolStr.c_str());

    if (protocolStr == "TCP") {
        g_externalInput.protocolType = ProtocolType::TCP;
    } else if (protocolStr == "RDMA") {
        g_externalInput.protocolType = ProtocolType::RDMA;
    } else {
        HCCL_ERROR("The pattern format is error. protocol should be TCP or RDMA.");
        return HCCL_E_PARA;
    }
    HCCL_INFO("SetProtocolType is %u", g_externalInput.protocolType);
    return HCCL_SUCCESS;
}

HcclResult InitParsesProtocol()
{
    HCCL_INFO("InitParsesProtocol start.");
    char realFile[PATH_MAX] = {0};
    // 异步点到点通信库跟随flowGW部署到910B DC形态的device侧后，原310P场景携带通信协议的resource.json不再存在
    // 通信库对外提供HCCL_NPU_NET_PROTOCOL环境变量，根据此变量获取网卡通信的协议
    const string npuNetProtocol = SalGetEnv("HCCL_NPU_NET_PROTOCOL");
    if (npuNetProtocol != "EmptyString") {
        CHK_RET(ParseNpuNetProtocol(npuNetProtocol));
        // 配置HCCL_NPU_NET_PROTOCOL为RDMA的情况下也可能存在resource.json
        std::string defaultPath = "/usr/local/Ascend/latest/conf/resource.json";
        HCCL_WARNING("can't find HELPER_RES_CONFIG or HELPER_RES_FILE_PATH, get protocol type from default path [%s]",
            defaultPath.c_str());
        if ((g_externalInput.protocolType == ProtocolType::RDMA) &&
            (realpath(defaultPath.c_str(), realFile) == nullptr)) {
            HCCL_INFO("default resource file is not exist.RDMA is used by default.");
            g_externalInput.remoteIsHdc = true;
        }
    } else {
        HCCL_INFO("environmental variable HCCL_NPU_NET_PROTOCOL is not set");
        CHK_RET(ParseResourceFileProtocol());
    }

    HCCL_INFO("Protocol[%d], remoteIsHdc[%d]", static_cast<s32>(g_externalInput.protocolType),
        g_externalInput.remoteIsHdc ? 1 : 0);
    return HCCL_SUCCESS;
}

HcclResult LoadJsonFile(const std::string& realName, nlohmann::json& fileContent)
{
    // 打开该文件前，判断该文件路径是否有效 规范
    char realFile[PATH_MAX] = {0};
    if (realpath(realName.c_str(), realFile) == nullptr) {
        HCCL_ERROR("[Load][File]errNo[0x%016llx] path %s is not a valid real path",
            HCOM_ERROR_CODE(HCCL_E_PARA), realName.c_str());
        return HCCL_E_PARA;
    }

    std::ifstream infile(realName.c_str(), std::ifstream::in);
    if (!infile) {
        HCCL_ERROR("[Load][ConfigFile]open file %s failed", realName.c_str());
        return HCCL_E_INTERNAL;
    } else {
        fileContent.clear();
        try {
            infile >> fileContent; // 将文件内容读取到json对象内
        } catch (...) {
            HCCL_ERROR("[Load][ConfigFile]errNo[0x%016llx] load file[%s] to json fail. please check json file format.",
                HCOM_ERROR_CODE(HCCL_E_INTERNAL), realName.c_str());
            infile.close();
            return HCCL_E_INTERNAL;
        }
    }
    infile.close();

    return HCCL_SUCCESS;
}

HcclResult ParseHcclAlgo()
{
    std::string hcclAlgo = SalGetEnv("HCCL_ALGO");
    if (hcclAlgo != "EmptyString") {
        CHK_RET(SetHcclAlgoConfig(hcclAlgo));
        HCCL_RUN_INFO("HCCL_ALGO set by environment to [%s]", hcclAlgo.c_str());
    } else {
        HCCL_RUN_INFO("HCCL_ALGO is not set");
    }
    return HCCL_SUCCESS;
}

HcclResult ParseRDMATrafficClass()
{
    std::string trafficClassEnv = SalGetEnv("HCCL_RDMA_TC");
    u32 rdmaTrafficClass = HCCL_RDMA_TC_DEFAULT;

    if (trafficClassEnv == "EmptyString") {
        HCCL_RUN_INFO("HCCL_RDMA_TC set by default to [%u]", rdmaTrafficClass);
        return HCCL_SUCCESS;
    }

    // 校验环境变量长度
    bool isEnvLenValid = CheckEnvLen(trafficClassEnv.c_str(), MAX_LEN_OF_DIGIT_ENV);

    CHK_PRT_RET(!isEnvLenValid,
        HCCL_ERROR("[Parse][TrafficClass]errNo[0x%016llx] Invalid HCCL_RDMA_TC env len, len is bigger than "\
            "[%u]. errorno[%d]", HCCL_ERROR_CODE(HCCL_E_PARA), MAX_LEN_OF_DIGIT_ENV, HCCL_E_PARA), HCCL_E_PARA);

    g_externalInput.rdmaTrafficClass = HCCL_RDMA_TC_DEFAULT;
    CHK_RET(IsAllDigit(trafficClassEnv.c_str()));

    HcclResult ret = SalStrToULong(trafficClassEnv.c_str(), HCCL_BASE_DECIMAL, rdmaTrafficClass);
    // 若转换出错或者设置的RDMATrafficClass不在有效范围内，报错
    CHK_PRT_RET((ret !=  HCCL_SUCCESS || rdmaTrafficClass < HCCL_RDMA_TC_MIN || rdmaTrafficClass > HCCL_RDMA_TC_MAX),
        HCCL_ERROR("[Parse][TrafficClass]HCCL_RDMA_TC[%s] is invalid. except: [%u, %u]",
            trafficClassEnv.c_str(), HCCL_RDMA_TC_MIN, HCCL_RDMA_TC_MAX), HCCL_E_PARA);
    // 设置的RDMATrafficClass需要是4的整数倍, 否则报错
    if (rdmaTrafficClass % HCCL_RDMA_TC_BASE != 0) {
        HCCL_ERROR("rdmaTrafficClass[%u] is not a multiple of [%u]", rdmaTrafficClass, HCCL_RDMA_TC_BASE);
        return HCCL_E_PARA;
    }
    g_externalInput.rdmaTrafficClass = rdmaTrafficClass;
    HCCL_RUN_INFO("HCCL_RDMA_TC set by environment to [%u]", rdmaTrafficClass);
    return HCCL_SUCCESS;
}

HcclResult ParseRDMAServerLevel()
{
    std::string serverLevelEnv = SalGetEnv("HCCL_RDMA_SL");
    u32 rdmaServerLevel = HCCL_RDMA_SL_DEFAULT;

    if (serverLevelEnv == "EmptyString") {
        HCCL_RUN_INFO("HCCL_RDMA_SL set by default to [%u]", rdmaServerLevel);
        return HCCL_SUCCESS;
    }

    // 校验环境变量长度
    bool isEnvLenValid = CheckEnvLen(serverLevelEnv.c_str(), MAX_LEN_OF_DIGIT_ENV);

    CHK_PRT_RET(!isEnvLenValid,
        HCCL_ERROR("[Parse][rdmaServerLevel]errNo[0x%016llx] Invalid HCCL_RDMA_SL env len, len is bigger than "\
            "[%u]. errorno[%d]", HCCL_ERROR_CODE(HCCL_E_PARA), MAX_LEN_OF_DIGIT_ENV, HCCL_E_PARA), HCCL_E_PARA);

    g_externalInput.rdmaServerLevel = HCCL_RDMA_SL_DEFAULT;
    CHK_RET(IsAllDigit(serverLevelEnv.c_str()));

    HcclResult ret = SalStrToULong(serverLevelEnv.c_str(), HCCL_BASE_DECIMAL, rdmaServerLevel);
    // 若转换出错或者设置的RDMAServerLevel不在有效范围内，报错
    CHK_PRT_RET((ret !=  HCCL_SUCCESS || rdmaServerLevel < HCCL_RDMA_SL_MIN || rdmaServerLevel > HCCL_RDMA_SL_MAX),
        HCCL_ERROR("[Parse][rdmaServerLevel]HCCL_RDMA_SL[%s] is invalid. except: [%u, %u]",
            serverLevelEnv.c_str(), HCCL_RDMA_SL_MIN, HCCL_RDMA_SL_MAX), HCCL_E_PARA);
    g_externalInput.rdmaServerLevel = rdmaServerLevel;
    HCCL_RUN_INFO("HCCL_RDMA_SL set by environment to [%u]", rdmaServerLevel);
    return HCCL_SUCCESS;
}

HcclResult ParseRDMATimeOut(std::pair<u32, u32> &rdmaTimeOutRange)
{
    u32 rdmaTimeOutMax;
#ifndef HCCD
    if (!IsGeneralServer()) {
        DevType deviceType;
        CHK_RET(hrtGetDeviceType(deviceType));
        rdmaTimeOutMax = (deviceType == DevType::DEV_TYPE_910_93 || deviceType == DevType::DEV_TYPE_910B)
            ? HCCL_RDMA_TIMEOUT_MAX_910_93
            : HCCL_RDMA_TIMEOUT_MAX;
    } else {
        rdmaTimeOutMax = HCCL_RDMA_TIMEOUT_MAX;
    }
#else
    rdmaTimeOutMax = HCCL_RDMA_TIMEOUT_MAX;
#endif
    rdmaTimeOutRange.first = HCCL_RDMA_TIMEOUT_MIN;
    rdmaTimeOutRange.second = rdmaTimeOutMax;
    std::string timeOutEnv = SalGetEnv("HCCL_RDMA_TIMEOUT");
    u32 rdmaTimeOut = HCCL_RDMA_TIMEOUT_DEFAULT;
    if (timeOutEnv == "EmptyString") {
        HCCL_RUN_INFO("HCCL_RDMA_TIMEOUT set by default to [%u]", rdmaTimeOut);
        return HCCL_SUCCESS;
    }

    // 校验环境变量长度
    bool isEnvLenValid = CheckEnvLen(timeOutEnv.c_str(), MAX_LEN_OF_DIGIT_ENV);

    CHK_PRT_RET(!isEnvLenValid,
        HCCL_ERROR("[Parse][TrafficClass]errNo[0x%016llx] Invalid HCCL_RDMA_TIMEOUT env len, len is bigger than "\
            "[%u]. errorno[%d]", HCCL_ERROR_CODE(HCCL_E_PARA), MAX_LEN_OF_DIGIT_ENV, HCCL_E_PARA), HCCL_E_PARA);

    g_externalInput.rdmaTimeOut = HCCL_RDMA_TIMEOUT_DEFAULT;
    CHK_RET(IsAllDigit(timeOutEnv.c_str()));

    HcclResult ret = SalStrToULong(timeOutEnv.c_str(), HCCL_BASE_DECIMAL, rdmaTimeOut);
    // 若转换出错或者设置的RDMATrafficClass不在有效范围内，报错
    CHK_PRT_RET(
        (ret != HCCL_SUCCESS || rdmaTimeOut < HCCL_RDMA_TIMEOUT_MIN || rdmaTimeOut > rdmaTimeOutMax),
        HCCL_ERROR("[Parse][TrafficClass]HCCL_RDMA_TIMEOUT[%s] is invalid. except: [%u, %u]",
            timeOutEnv.c_str(),
            HCCL_RDMA_TIMEOUT_MIN,
            rdmaTimeOutMax),
        HCCL_E_PARA);

    g_externalInput.rdmaTimeOut = rdmaTimeOut;
    HCCL_RUN_INFO("HCCL_RDMA_TIMEOUT set by environment to [%u]", rdmaTimeOut);
    return HCCL_SUCCESS;
}

HcclResult ParseRDMARetryCnt()
{
    std::string retryCntEnv = SalGetEnv("HCCL_RDMA_RETRY_CNT");
    u32 rdmaRetryCnt = HCCL_RDMA_RETRY_CNT_DEFAULT;
    if (retryCntEnv == "EmptyString") {
        HCCL_RUN_INFO("HCCL_RDMA_RETRY_CNT set by default to [%u]", rdmaRetryCnt);
        return HCCL_SUCCESS;
    }

    // 校验环境变量长度
    bool isEnvLenValid = CheckEnvLen(retryCntEnv.c_str(), MAX_LEN_OF_DIGIT_ENV);

    CHK_PRT_RET(!isEnvLenValid,
        HCCL_ERROR("[Parse][rdmaRetryCnt]errNo[0x%016llx] Invalid HCCL_RDMA_RETRY_CNT env len, len is bigger than "\
            "[%u]. errorno[%d]", HCCL_ERROR_CODE(HCCL_E_PARA), MAX_LEN_OF_DIGIT_ENV, HCCL_E_PARA), HCCL_E_PARA);

    g_externalInput.rdmaRetryCnt = HCCL_RDMA_RETRY_CNT_DEFAULT;
    CHK_RET(IsAllDigit(retryCntEnv.c_str()));

    HcclResult ret = SalStrToULong(retryCntEnv.c_str(), HCCL_BASE_DECIMAL, rdmaRetryCnt);
    // 若转换出错或者设置的RDMAServerLevel不在有效范围内，报错
    CHK_PRT_RET(
        (ret != HCCL_SUCCESS || rdmaRetryCnt < HCCL_RDMA_RETRY_CNT_MIN || rdmaRetryCnt > HCCL_RDMA_RETRY_CNT_MAX),
        HCCL_ERROR("[Parse][rdmaRetryCnt]HCCL_RDMA_RETRY_CNT[%s] is invalid. except: [%u, %u]", retryCntEnv.c_str(),
        HCCL_RDMA_RETRY_CNT_MIN, HCCL_RDMA_RETRY_CNT_MAX),
        HCCL_E_PARA);
    g_externalInput.rdmaRetryCnt = rdmaRetryCnt;
    HCCL_RUN_INFO("HCCL_RDMA_RETRY_CNT set by environment to [%u]", rdmaRetryCnt);
    return HCCL_SUCCESS;
}

HcclResult ParseCannVersion()
{
    const std::string cannEnv = SalGetEnv("LD_LIBRARY_PATH");
    // 环境变量不存在
    if (cannEnv == "EmptyString") {
        HCCL_INFO("[CannVersion][Verification]environmental variable LD_LIBRARY_PATH is not set.");
        return HCCL_SUCCESS;
    }

    // 环境变量过长
    if (cannEnv.length() > MAX_LEN_OF_CANN_ENV) {
        HCCL_INFO("[CannVersion][Verification]environmental variable LD_LIBRARY_PATH is too long, actual len[%u], "
            "maxlen[%lu]", cannEnv.length(), MAX_LEN_OF_CANN_ENV);
        return HCCL_SUCCESS;
    }

    HcclResult ret = HCCL_SUCCESS;
    std::string cannVersionPath;   // 存放cann安装路径
    if (GetCannVersionPath(cannEnv, "/runtime", cannVersionPath) == HCCL_SUCCESS) {
        cannVersionPath += "/version.info";
        ret = LoadCannVersionInfoFile(cannVersionPath, "Version=");
    } else if (GetCannVersionPath(cannEnv, "/latest", cannVersionPath) == HCCL_SUCCESS) {
        cannVersionPath += "/version.cfg";
        ret = LoadCannVersionInfoFile(cannVersionPath, "runtime_running_version=[");
    } else {
        HCCL_INFO("[CannVersion][Verification]cannot found version file in %s.", cannEnv.c_str());
    }
    return ret;
}

HcclResult GetCannVersionPath(const std::string &cannEnvStr, const std::string &keyStr, std::string &cannVersionPath)
{
    std::string tempPath;   // 存放临时路径
    // 查找cann安装路径
    for (u32 i = 0; i < cannEnvStr.length(); ++i) {
        // 环境变量中存放的每段路径之间以':'隔开
        if (cannEnvStr[i] != ':') {
            tempPath += cannEnvStr[i];
        }
        // 对存放CANN版本文件的路径进行搜索, 有两种情况
        // 一种是*/latest/version.cfg
        // 另一种是*/runtime/version.info
        if (cannEnvStr[i] == ':' || i == cannEnvStr.length() - 1) {
            size_t found = tempPath.find(keyStr);
            // 防止出现类似/runtime*/的情况
            if (found == string::npos) {
                tempPath.clear();
                continue;
            }
            if (tempPath.length() <= found + keyStr.length() || tempPath[found + keyStr.length()] == '/') {
                cannVersionPath = tempPath.substr(0, found + keyStr.length());
                break;
            }
            tempPath.clear();
        }
    }
    // 路径为空
    if (cannVersionPath.empty()) {
        return HCCL_E_NOT_FOUND;
    }
    return HCCL_SUCCESS;
}

HcclResult LoadCannVersionInfoFile(const std::string &realName, const std::string &keyStr)
{
    // 打开该文件前，判断该文件路径是否有效、规范
    char realFile[PATH_MAX] = {0};
    if (realpath(realName.c_str(), realFile) == nullptr) {
        HCCL_INFO("[CannVersion][Verification]cann version path %s is not a valid real path",
            realName.c_str());
        return HCCL_E_NOT_FOUND;
    }
    HCCL_INFO("Load CannVersion InfoFile in %s", realFile);

    // realFile转str,然后open这个str
    ifstream infile;
    infile.open(realFile);

    if (!infile.is_open()) {
        HCCL_INFO("[CannVersion][Verification]%s does not exist.", realFile);
        return HCCL_E_NOT_FOUND;
    }

    HcclResult ret = HCCL_SUCCESS;
    // 逐行读取，结果放在line中，寻找带有keyStr的字符串
    string line;
    s32 maxRows = 100; // 在文件中读取的最长行数为100，避免超大文件长时间读取
    while (getline(infile, line)) {
        --maxRows;
        CHK_PRT_BREAK(maxRows < 0, \
            HCCL_WARNING("[CannVersion][Verification]version file content is too long."), \
            ret = HCCL_E_NOT_FOUND);
        u32 found = line.find(keyStr);
        // 版本字段的两种模式
        // runtime目录下, version.info文件, Version=1.83.T8.0.B128
        // latest目录下, version.cfg文件, runtime_running_version=[1.83.T8.0.B128:CANN-1.83]
        if (found == 0) {
            u32 startPos = keyStr.length(); // 版本字符串开始位置
            u32 endPos = min(line.find(":"), line.length()); // 版本字符串在":"或结尾处结束
            // 版本字符串为空
            CHK_PRT_BREAK(endPos <= startPos, \
                HCCL_WARNING("[CannVersion][Verification]cannVersion is invalid."), \
                ret = HCCL_E_NOT_FOUND);

            u32 len = endPos - startPos; // 版本字符串长度
            g_externalInput.cannVersion = line.substr(startPos, len); // 从keyStr截断
            HCCL_INFO("[Parse][CannVersion]success, CannVersion is %s ", g_externalInput.cannVersion.c_str());
            break;
        }
    }
    infile.close();
    return ret;
}

HcclResult ParseCclBufferSize()
{
    std::string hcclBufferSize = SalGetEnv("HCCL_BUFFSIZE");
    u32 cclBufferSize = HCCL_CCL_COMM_DEFAULT_BUFFER_SIZE;
    if (hcclBufferSize == "EmptyString") {
        HCCL_RUN_INFO("HCCL_BUFFSIZE set by default to [%u]M", cclBufferSize);
        return HCCL_SUCCESS;
    }

    // 校验环境变量长度
    bool isEnvLenValid = CheckEnvLen(hcclBufferSize.c_str(), MAX_LEN_OF_DIGIT_ENV);

    CHK_PRT_RET(!isEnvLenValid,
        HCCL_ERROR("[Parse][CclBufferSize]errNo[0x%016llx] Invalid HCCL_BUFFSIZE env len, len is bigger than "\
            "[%u]. errorno[%d]", HCCL_ERROR_CODE(HCCL_E_PARA), MAX_LEN_OF_DIGIT_ENV, HCCL_E_PARA), HCCL_E_PARA);

    u64 cclBufFixedCalcSize = HCCL_CCL_COMM_FIXED_CALC_BUFFER_SIZE;
    CHK_RET(IsAllDigit(hcclBufferSize.c_str()));

    HcclResult ret = SalStrToULong(hcclBufferSize.c_str(), HCCL_BASE_DECIMAL, cclBufferSize);
    // 若转换出错或者设置的CclBufferSize不在有效范围内，报错
    CHK_PRT_RET(
        (ret != HCCL_SUCCESS || cclBufferSize < HCCL_CCL_COMM_BUFFER_MIN),
        HCCL_ERROR("[Parse][CclBufferSize]external input CclBufferSize[%uM] should be greater than %uM",
        cclBufferSize, HCCL_CCL_COMM_BUFFER_MIN), HCCL_E_PARA);
    g_externalInput.cclBufferSize = static_cast<u64>(cclBufferSize * cclBufFixedCalcSize);
    HCCL_RUN_INFO("HCCL_BUFFSIZE set by environment to [%u]M", cclBufferSize);
    return HCCL_SUCCESS;
}

HcclResult ParseHcclOpBasedFFTSModeEnable()
{
    std::string enableFftsEnv = SalGetEnv("HCCL_OP_BASE_FFTS_MODE_ENABLE");
    if (enableFftsEnv == "EmptyString") {
        HCCL_INFO("HCCL_OP_BASE_FFTS_MODE_ENABLE set by default to [true]");
        return HCCL_SUCCESS;
    }
    g_externalInput.enableFfts = false;
    std::transform(enableFftsEnv.begin(), enableFftsEnv.end(), enableFftsEnv.begin(), ::toupper);
    if ("TRUE" == enableFftsEnv) {
        g_externalInput.enableFfts = true;
    }
    // 资料未公开的环境变量，不能通过默认日志级别输出，调整为info级别
    HCCL_INFO("HCCL_OP_BASE_FFTS_MODE_ENABLE set by environment to [%s]", enableFftsEnv.c_str());
    return HCCL_SUCCESS;
}

void SetIfProfile(bool ifProfile)
{
    g_ifProf = ifProfile; 
}

const bool& GetIfProfile()
{
    return g_ifProf;
}

void SetProfConfig(u64 profConfig)
{
    g_externalInput.profConfig = profConfig;
    HCCL_INFO("[%s]Set profConfig[%x]", __func__, profConfig);
}

HcclResult ParseTaskExceptionSwitch()
{
    // task_exception_handler调测开关，默认关闭 (0)
    std::string taskExceptionSwitchEnv = SalGetEnv("HCCL_DIAGNOSE_ENABLE");
    if (taskExceptionSwitchEnv == "EmptyString") {
        HCCL_RUN_INFO("HCCL_DIAGNOSE_ENABLE set by default to [0]");
        return HCCL_SUCCESS;
    }
    u32 taskExceptionSwitchConfig = 0;
    bool isEnvLenValid = CheckEnvLen(taskExceptionSwitchEnv.c_str(), MAX_LEN_OF_DIGIT_ENV);
    CHK_PRT_RET(!isEnvLenValid, HCCL_ERROR("[Parse][TaskExceptionSwitch]errNo[0x%016llx] Invalid" \
        " HCCL_DIAGNOSE_ENABLE env len, len is bigger than [%u]. errorno[%d]",
        HCCL_ERROR_CODE(HCCL_E_PARA), MAX_LEN_OF_DIGIT_ENV, HCCL_E_PARA), HCCL_E_PARA);
    CHK_RET(IsAllDigit(taskExceptionSwitchEnv.c_str()));
    CHK_RET(SalStrToULong(taskExceptionSwitchEnv.c_str(), HCCL_BASE_DECIMAL, taskExceptionSwitchConfig));
    if ((taskExceptionSwitchConfig != 0) && (taskExceptionSwitchConfig != 1)) {
        HCCL_ERROR("[Get][TaskExceptionSwitch]environmental digit variable error, taskExceptionSwitchConfig[%u]",
            taskExceptionSwitchConfig);
        return HCCL_E_PARA;
    }
    HCCL_RUN_INFO("HCCL_DIAGNOSE_ENABLE set by environment to [%u]", taskExceptionSwitchConfig);
    g_externalInput.taskExceptionSwitch = taskExceptionSwitchConfig;
    return HCCL_SUCCESS;
}

HcclResult ParseRdmaQpsPerConnection()
{
    g_externalInput.qpsPerConnection = HCCL_QPS_PER_CONNECTION_DEFAULT;
    std::string rdmaQpsPerConnectionEnv = SalGetEnv("HCCL_RDMA_QPS_PER_CONNECTION");
    if (rdmaQpsPerConnectionEnv == "EmptyString") {
        HCCL_DEBUG("HCCL_RDMA_QPS_PER_CONNECTION is set to default value [1]");
        return HCCL_SUCCESS;
    }
    // 校验环境变量长度
    bool isEnvLenValid = CheckEnvLen(rdmaQpsPerConnectionEnv.c_str(), MAX_LEN_OF_DIGIT_ENV);
    CHK_PRT_RET(!isEnvLenValid,
        HCCL_ERROR("[Parse][RdmaQpsPerConnectionEnv]errNo[0x%016llx] Invalid RdmaQpsPerConnectionEnv env len,"
        "len is bigger than [%u]. errorno[%d]",
        HCCL_ERROR_CODE(HCCL_E_PARA), MAX_LEN_OF_DIGIT_ENV, HCCL_E_PARA),
        HCCL_E_PARA);

    u32 qpsPerConnection = HCCL_QPS_PER_CONNECTION_DEFAULT;
    CHK_RET(IsAllDigit(rdmaQpsPerConnectionEnv.c_str()));
    HcclResult ret = SalStrToULong(rdmaQpsPerConnectionEnv, HCCL_BASE_DECIMAL, qpsPerConnection);
    if (ret != HCCL_SUCCESS || (qpsPerConnection < HCCL_QPS_PER_CONNECTION_DEFAULT) ||
        (qpsPerConnection > HCCL_QPS_PER_CONNECTION_MAX)) {
        HCCL_ERROR("[Parse][RdmaQpsPerConnectionEnv]environmental variable HCCL_RDMA_QPS_PER_CONNECTION error,"
            "errNo[0x%016llx] qpsPerConnection[%s] Range[%u, %u] Recommended Range[1, 8]",
            HCOM_ERROR_CODE(ret), rdmaQpsPerConnectionEnv.c_str(), HCCL_QPS_PER_CONNECTION_DEFAULT,
            HCCL_QPS_PER_CONNECTION_MAX);
        g_externalInput.qpsPerConnection = HCCL_QPS_PER_CONNECTION_DEFAULT;
        return HCCL_E_PARA;
    }
    g_externalInput.qpsPerConnection = qpsPerConnection;
    HCCL_RUN_INFO("environmental variable HCCL_RDMA_QPS_PER_CONNECTION is set to [%d]", qpsPerConnection);
    return HCCL_SUCCESS;
}

HcclResult ParseMultiQpThreshold()
{
    g_externalInput.multiQpThreshold = HCCL_MULTI_QP_THRESHOLD_DEFAULT;
    std::string strMultiQpThresholdEnv = SalGetEnv("HCCL_MULTI_QP_THRESHOLD");
    if (strMultiQpThresholdEnv == "EmptyString") {
        HCCL_DEBUG("HCCL_MULTI_QP_THRESHOLD is set to default value [%u]", HCCL_MULTI_QP_THRESHOLD_DEFAULT);
        return HCCL_SUCCESS;
    }
    // 校验环境变量长度
    bool isEnvLenValid = CheckEnvLen(strMultiQpThresholdEnv.c_str(), MAX_LEN_OF_DIGIT_ENV);
    CHK_PRT_RET(!isEnvLenValid,
        HCCL_ERROR("[Parse][MultiQpThresholdEnv]errNo[0x%016llx] Invalid MultiQpThresholdEnv env len,"
        "len is bigger than [%u]. errorno[%d]",
        HCCL_ERROR_CODE(HCCL_E_PARA), MAX_LEN_OF_DIGIT_ENV, HCCL_E_PARA),
        HCCL_E_PARA);

    u32 multiQpThreshold = HCCL_MULTI_QP_THRESHOLD_DEFAULT;
    CHK_RET(IsAllDigit(strMultiQpThresholdEnv.c_str()));
    HcclResult ret = SalStrToULong(strMultiQpThresholdEnv, HCCL_BASE_DECIMAL, multiQpThreshold);
    if (ret != HCCL_SUCCESS || multiQpThreshold == 0 ||  multiQpThreshold > HCCL_MULTI_QP_THRESHOLD_MAX) {
        HCCL_ERROR("[Parse][MultiQpThresholdEnv]environmental variable HCCL_MULTI_QP_THRESHOLD error,"
            "errNo[0x%016llx] multiQpThreshold[%s] Range[1, %u]",
            HCOM_ERROR_CODE(ret), strMultiQpThresholdEnv.c_str(), HCCL_MULTI_QP_THRESHOLD_MAX);
        g_externalInput.multiQpThreshold = HCCL_MULTI_QP_THRESHOLD_DEFAULT;
        return HCCL_E_PARA;
    }
    g_externalInput.multiQpThreshold = multiQpThreshold;
    HCCL_RUN_INFO("environmental variable HCCL_MULTI_QP_THRESHOLD is set to [%d]", multiQpThreshold);
    return HCCL_SUCCESS;
}

HcclResult ParseEntryLogEnable()
{
    std::string enableEntryLogEnv = SalGetEnv("HCCL_ENTRY_LOG_ENABLE");
    if (enableEntryLogEnv == "EmptyString") {
        HCCL_RUN_INFO("HCCL_ENTRY_LOG_ENABLE set by default to [0]");
        return HCCL_SUCCESS;
    }
    if (enableEntryLogEnv != "0" && enableEntryLogEnv != "1") {
        HCCL_ERROR("[Parser][EntryLogEnable]environmental variable HCCL_ENTRY_LOG_ENABLE [%s] is invalid, set by "
                     "default to [0]", enableEntryLogEnv.c_str());
        return HCCL_E_PARA;
    }
    g_externalInput.enableEntryLog = false;
    if (enableEntryLogEnv == "1") {
        g_externalInput.enableEntryLog = true;
    }
    HCCL_RUN_INFO("HCCL_ENTRY_LOG_ENABLE set by environment to [%u]", g_externalInput.enableEntryLog);
    return HCCL_SUCCESS;
}

HcclResult ParseInterLinkType()
{
    std::string interHccsDisableEnv = SalGetEnv("HCCL_INTER_HCCS_DISABLE");
    if (interHccsDisableEnv == "EmptyString") {
        HCCL_INFO("HCCL_INTER_HCCS_DISABLE is not set, default value is %d.", g_externalInput.interHccsDisable);
        return HCCL_SUCCESS;
    }
    std::transform(interHccsDisableEnv.begin(), interHccsDisableEnv.end(), interHccsDisableEnv.begin(), ::toupper);
    if ("TRUE" == interHccsDisableEnv) {
        g_externalInput.interHccsDisable = true;
    } else if ("FALSE" == interHccsDisableEnv) {
        g_externalInput.interHccsDisable = false;
    } else {
        HCCL_ERROR("HCCL_INTER_HCCS_DISABLE %s is invalid, expect true or false.", interHccsDisableEnv.c_str());
        return HCCL_E_PARA;
    }
    HCCL_RUN_INFO("environmental variable HCCL_INTER_HCCS_DISABLE is set to [%u]", g_externalInput.interHccsDisable);
    return HCCL_SUCCESS;
}

HcclResult ParseInterVnicDisable()
{
    std::string interVnicDisableEnv = SalGetEnv("HCCL_INTER_VNIC_DISABLE");
    if (interVnicDisableEnv == "EmptyString") {
        HCCL_INFO("HCCL_INTER_VNIC_DISABLE is not set, default value is %d.", g_externalInput.interVnicDisable);
        return HCCL_SUCCESS;
    }
    std::transform(interVnicDisableEnv.begin(), interVnicDisableEnv.end(), interVnicDisableEnv.begin(), ::toupper);
    if ("TRUE" == interVnicDisableEnv) {
        g_externalInput.interVnicDisable = true;
    } else if ("FALSE" == interVnicDisableEnv) {
        g_externalInput.interVnicDisable = false;
    } else {
        HCCL_ERROR("HCCL_INTER_VNIC_DISABLE %s is invalid, expect true or false.", interVnicDisableEnv.c_str());
        return HCCL_E_PARA;
    }
    HCCL_RUN_INFO("environmental variable HCCL_INTER_VNIC_DISABLE is set to [%u]", g_externalInput.interVnicDisable);
    return HCCL_SUCCESS;
}

HcclResult ParseOpExpansion()
{
    std::string enableEntryLogEnv = SalGetEnv("HCCL_OP_EXPANSION_MODE");
    g_externalInput.aicpuUnfold = false;
    g_externalInput.aivMode = false;
    if (IsGeneralServer()) {
        HCCL_RUN_INFO("HCCL_OP_EXPANSION_MODE is not set, aicpuUnfold is [%u], aivMode is [%u]",
            g_externalInput.aicpuUnfold, g_externalInput.aivMode);
        return HCCL_SUCCESS;
    }

#ifndef HCCD
    DevType deviceType;
    CHK_RET(hrtGetDeviceType(deviceType));
    // 910_93默认打开AICPU展开
    if (deviceType == DevType::DEV_TYPE_910_93) {
        g_externalInput.aicpuUnfold = true;
    }
    if (enableEntryLogEnv == "EmptyString") {
        HCCL_RUN_INFO("HCCL_OP_EXPANSION_MODE is not set, aicpuUnfold is [%u], aivMode is [%u]",
            g_externalInput.aicpuUnfold, g_externalInput.aivMode);
        return HCCL_SUCCESS;
    }
    if (enableEntryLogEnv == "AI_CPU" && (deviceType == DevType::DEV_TYPE_910B || deviceType == DevType::DEV_TYPE_910)) {
        HCCL_WARNING("910B and 910 do not support AICPU unfold.");
        return HCCL_SUCCESS;
    } else if (enableEntryLogEnv == "AI_CPU") {
        g_externalInput.aicpuUnfold = true;
    } else if (enableEntryLogEnv == "AIV") {
        if (g_externalInput.hcclDeterministic == true) {
            HCCL_WARNING("Deterministic do not support aiv");
        }
        g_externalInput.aivMode = true;
    } else if (enableEntryLogEnv == "HOST") {
        g_externalInput.aivMode = false;
        g_externalInput.aicpuUnfold = false;
    } else {
        HCCL_ERROR("HCCL_OP_EXPANSION_MODE is set to [%s], which is incorrect. Please check",
            enableEntryLogEnv.c_str());
        return HCCL_E_PARA;
    }
#endif
    HCCL_RUN_INFO("environmental variable HCCL_OP_EXPANSION_MODE is set to [%s], aicpuUnfold is [%u], aivMode is [%u].",
        enableEntryLogEnv.c_str(), g_externalInput.aicpuUnfold, g_externalInput.aivMode);
    return HCCL_SUCCESS;
}

HcclResult ParseMc2DebugMode()
{
    std::string debugMode = SalGetEnv("ASCEND_MC2_DEBUG_MODE");
    if (debugMode == "EmptyString") {
        HCCL_INFO("environmental variable ASCEND_MC2_DEBUG_MODE is not set");
        return HCCL_SUCCESS;
    }

    // 校验环境变量长度
    bool isEnvLenValid = CheckEnvLen(debugMode.c_str(), MAX_LEN_OF_DIGIT_ENV);

    CHK_PRT_RET(!isEnvLenValid,
        HCCL_ERROR("[Parse][mc2debugMode]errNo[0x%016llx] Invalid ASCEND_MC2_DEBUG_MODE env len, len is bigger than "\
            "[%u]. errorno[%d]", HCCL_ERROR_CODE(HCCL_E_PARA), MAX_LEN_OF_DIGIT_ENV, HCCL_E_PARA), HCCL_E_PARA);

    CHK_RET(IsAllDigit(debugMode.c_str()));

    u32 mc2DebugValue = HCCL_CCL_COMM_DEFAULT_BUFFER_SIZE;
    HcclResult ret = SalStrToULong(debugMode.c_str(), HCCL_BASE_DECIMAL, mc2DebugValue);
    // 若转换出错或者设置的mc2DebugValue不在有效范围内，报错
    CHK_PRT_RET((ret != HCCL_SUCCESS),
        HCCL_ERROR("[Parse][CclBufferSize]external input mc2DebugValue[%u] should is 1,2,4,6,8,16",
        mc2DebugValue), HCCL_E_PARA);
    g_externalInput.mc2DebugMode = mc2DebugValue;
    HCCL_INFO("external input mc2DebugValue is set to [%u].", mc2DebugValue);

    return HCCL_SUCCESS;
}

HcclResult ParseLogConfig()
{
    std::string logConfigEnv = SalGetEnv("HCCL_LOG_CONFIG");
    if (logConfigEnv == "EmptyString") {
        HCCL_INFO("HCCL_LOG_CONFIG set by default to [0]");
        return HCCL_SUCCESS;
    }
    // 校验环境变量长度
    bool isEnvLenValid = CheckEnvLen(logConfigEnv.c_str(), MAX_LEN_OF_DIGIT_ENV);

    CHK_PRT_RET(!isEnvLenValid,
        HCCL_ERROR("[ParseLogConfig]errNo[0x%016llx] Invalid HCCL_LOG_CONFIG env len, len is bigger than "\
            "[%u]. errorno[%d]", HCCL_ERROR_CODE(HCCL_E_PARA), MAX_LEN_OF_DIGIT_ENV, HCCL_E_PARA), HCCL_E_PARA);

    CHK_RET(IsAllDigit(logConfigEnv.c_str()));

    u32 logConfigValue = 0;
    HcclResult ret = SalStrToULong(logConfigEnv.c_str(), HCCL_BASE_DECIMAL, logConfigValue);
    // 若转换出错或者设置的logConfigValue不在有效范围内，报错
    CHK_PRT_RET((ret != HCCL_SUCCESS),
        HCCL_ERROR("[ParseLogConfig]external input logConfigValue[%u] should is 0,1",
        logConfigValue), HCCL_E_PARA);
    g_externalInput.logConfig = logConfigValue;
    HCCL_INFO("HCCL_LOG_CONFIG set by environment to [%u].", logConfigValue);
    return HCCL_SUCCESS;
}

HcclResult SplitHcclRetryEnable(const std::string &retryConfig, std::vector<std::string> &retryEnables)
{
#ifndef CCL_KERNEL_AICPU
    std::string remainRetryConfig;
    std::size_t found = retryConfig.find(",");
    if ((found == 0) || (found == (retryConfig.length() - 1))) {
        HCCL_ERROR("[SplitHcclRetryEnable] algo config is invalid.");
        return HCCL_E_PARA;
    } else if (found != std::string::npos) {
        remainRetryConfig = retryConfig.substr(found + 1);
    } else {
        // 最后一组配置,剩余的字符串为空
    }
    retryEnables.push_back(retryConfig.substr(0, found));

    if (retryEnables.size() > HCCL_RETRY_ENABLE_LEVEL_NUM) {
        HCCL_ERROR("[SplitHcclRetryEnable] retryEnable config is invalid. retryEnable level is more than %u.",
            HCCL_RETRY_ENABLE_LEVEL_NUM);
        return HCCL_E_PARA;
    }
    if (!remainRetryConfig.empty()) {
        CHK_RET(SplitHcclRetryEnable(remainRetryConfig, retryEnables));
    }
#endif
    return HCCL_SUCCESS;
}

HcclResult CollectRetryEnableFromConfig(const std::vector<std::string> &retryEnables)
{
#ifndef CCL_KERNEL_AICPU
    const std::map<std::string, u32> hcclRetryLevelMap = {
        {"L0", HCCL_RETRY_ENABLE_LEVEL_0}, {"L1", HCCL_RETRY_ENABLE_LEVEL_1}, {"L2", HCCL_RETRY_ENABLE_LEVEL_2}};

    std::map<std::string, u32> countHcclRetryLevelMap = {{"L0", 0}, {"L1", 0}, {"L2", 0}};

    const std::map<std::string, bool> hcclRetryEnableMap = {{"0", false}, {"1", true}};
    for (auto retryEnableLevel : retryEnables) {
        u32 level = 0;
        bool retryEnable = false;
        std::size_t found = retryEnableLevel.find(":");
        if ((found == 0) || (found == (retryEnableLevel.length() - 1))) {
            HCCL_ERROR("[CollectRetryEnableFromConfig] Hccl retryEnableLevel is invalid.");
            return HCCL_E_PARA;
        }
        std::string orginalLevel = retryEnableLevel.substr(0, found);
        std::string orginalRetryEnable = retryEnableLevel.substr(found + 1);
        // 检查是否存在重复配置level
        auto iterCountRetryLevel = countHcclRetryLevelMap.find(orginalLevel);
        if (iterCountRetryLevel == countHcclRetryLevelMap.end()) {
            HCCL_ERROR("[CollectRetryEnableFromConfig] Retry config is invalid, level %s is not supported.",
                orginalLevel.c_str());
            return HCCL_E_PARA;
        }
        if (countHcclRetryLevelMap[orginalLevel] == 1) {
            HCCL_ERROR("[CollectRetryEnableFromConfig] Retry config level[%s] is repeated, expect: L0:0, L1:0, L2:0",
                orginalLevel.c_str());
            return HCCL_E_PARA;
        }
        countHcclRetryLevelMap[orginalLevel] += 1;
        // 获取level和对应的retryEnable，并赋值给g_externalInput.hcclRetryConfig
        auto iterRetryLevel = hcclRetryLevelMap.find(orginalLevel);
        if (iterRetryLevel == hcclRetryLevelMap.end()) {
            HCCL_ERROR("[CollectRetryEnableFromConfig] Retry config is invalid, level %s is not supported.",
                orginalLevel.c_str());
            return HCCL_E_PARA;
        }
        auto iterRetryEnable = hcclRetryEnableMap.find(orginalRetryEnable);
        if (iterRetryEnable == hcclRetryEnableMap.end()) {
            HCCL_ERROR("[CollectRetryEnableFromConfig] Retry config is invalid, retryEnable %s is not supported.",
                orginalRetryEnable.c_str());
            return HCCL_E_PARA;
        }
        level = iterRetryLevel->second;
        retryEnable = iterRetryEnable->second;
        g_externalInput.hcclRetryConfig[level] = retryEnable;
    }
#endif
    return HCCL_SUCCESS;
}

HcclResult ParseRetryEnable()
{
#ifndef CCL_KERNEL_AICPU
    // 默认都设置成true
    for (u32 level = 0; level < HCCL_RETRY_ENABLE_LEVEL_NUM; ++level) {
        g_externalInput.hcclRetryConfig[level] = false;
    }
    std::string hcclRetryEnable = SalGetEnv("HCCL_OP_RETRY_ENABLE");
    if (hcclRetryEnable == "EmptyString") {
        HCCL_RUN_INFO(
            "[ParseRetryEnable] HCCL_OP_RETRY_ENABLE is not set. The retryEnable of all levels is set to false.");
        return HCCL_SUCCESS;
    }
    // 去除空格
    std::string retryConfig = hcclRetryEnable;
    retryConfig.erase(std::remove(retryConfig.begin(), retryConfig.end(), ' '), retryConfig.end());

    if (retryConfig.empty()) {
        HCCL_RUN_INFO("[ParseRetryEnable] Hccl retry config is empty. The retryEnable of all levels is set to false.");
        return HCCL_SUCCESS;
    }

    std::vector<std::string> retryEnables;
    HcclResult ret = SplitHcclRetryEnable(retryConfig, retryEnables);
    CHK_PRT_RET(ret != HCCL_SUCCESS,
        HCCL_ERROR("[CollectRetryEnableFromConfig] Hccl retry config[%s] is invalid. "
                   "expect: L0:0, L1:0, L2:0",
            retryConfig.c_str()),
        ret);

    CHK_RET(CollectRetryEnableFromConfig(retryEnables));
    HCCL_RUN_INFO("[ParseRetryEnable] HCCL_OP_RETRY_ENABLE set by environment variable to [%s].", retryConfig.c_str());
#endif
    return HCCL_SUCCESS;
}

HcclResult ParseRdmaSdmaConcurrentEnable()
{
    std::string rdmaSdmaConcurrentEnEnv = SalGetEnv("HCCL_CONCURRENT_ENABLE");
    // 未设置，默认不使能
    if (rdmaSdmaConcurrentEnEnv == "EmptyString") {
        HCCL_INFO("HCCL_CONCURRENT_ENABLE is not set, default value is [0].");
        return HCCL_SUCCESS;
    }
    if ("1" == rdmaSdmaConcurrentEnEnv) {
        if (g_externalInput.interHccsDisable) {
            HCCL_ERROR("HCCL_CONCURRENT_ENABLE and HCCL_INTER_HCCS_DISABLE can not both set to 1 at the same time");
            return HCCL_E_PARA;
        }
        if (g_externalInput.aicpuUnfold || g_externalInput.aivMode) {
            g_externalInput.enableRdmaSdmaConcurrent = false;
            HCCL_RUN_INFO("HCCL_CONCURRENT_ENABLE can't be set to 1 when HCCL_OP_EXPANSION_MODE is AI_CPU or AIV, so "
                "HCCL_CONCURRENT_ENABLE is set to 0");
            return HCCL_SUCCESS;
        }
        g_externalInput.enableRdmaSdmaConcurrent = true;
    } else if ("0" == rdmaSdmaConcurrentEnEnv) {
        g_externalInput.enableRdmaSdmaConcurrent = false;
    } else {
        HCCL_ERROR("HCCL_CONCURRENT_ENABLE %s is invalid, expect 0 or 1.", rdmaSdmaConcurrentEnEnv.c_str());
        return HCCL_E_PARA;
    }
    HCCL_RUN_INFO("environmental variable HCCL_CONCURRENT_ENABLE is set to [%u].",
        g_externalInput.enableRdmaSdmaConcurrent);

    return HCCL_SUCCESS;
}

HcclResult ParseOpCounterEnable()
{
    std::string opCounterEnv = SalGetEnv("HCCL_OP_COUNTER_ENABLE");
    if (opCounterEnv == "EmptyString") {
        HCCL_RUN_INFO("HCCL_OP_COUNTER_ENABLE set by default to [%d]", g_externalInput.opCounterEnable);
        return HCCL_SUCCESS;
    }
    if (opCounterEnv != "0" && opCounterEnv != "1") {
        HCCL_ERROR("HCCL_OP_COUNTER_ENABLE is %s, it should be 0 or 1", opCounterEnv.c_str());
        return HCCL_E_PARA;
    }
    if (opCounterEnv == "1") {
        g_externalInput.opCounterEnable = true;
    } else {
        g_externalInput.opCounterEnable = false;
    }
    HCCL_RUN_INFO("HCCL_OP_COUNTER_ENABLE set by environment to [%u].", g_externalInput.opCounterEnable);
    return HCCL_SUCCESS;
}

HcclResult ParseStuckDetectTime()
{
    std::string detectTimeEnv = SalGetEnv("HCCL_STUCK_DETECT_TIME");
    if (detectTimeEnv != "EmptyString") {
        bool isEnvLenValid = CheckEnvLen(detectTimeEnv.c_str(), MAX_LEN_OF_DIGIT_ENV);
        CHK_PRT_RET(!isEnvLenValid,
            HCCL_ERROR(
            "[Parse][HCCL_STUCK_DETECT_TIME]errNo[0x%016llx] Invalid  detectTimeEnv env len, len is bigger than "
            "[%u]. errorno[%d]",
            HCCL_ERROR_CODE(HCCL_E_PARA), MAX_LEN_OF_DIGIT_ENV, HCCL_E_PARA),
            HCCL_E_PARA);

        CHK_RET(IsAllDigit(detectTimeEnv.c_str()));
        HcclResult ret = SalStrToInt(detectTimeEnv, HCCL_BASE_DECIMAL, g_externalInput.stuckDetectTime);
        if (ret != HCCL_SUCCESS) {
            HCCL_ERROR("[Parse][HCCL_STUCK_DETECT_TIME]environmental variable HCCL_STUCK_DETECT_TIME error, "
                "errNo[0x%016llx] detectTimeEnv[%s]", HCOM_ERROR_CODE(ret), detectTimeEnv.c_str());
            return HCCL_E_PARA;
        }
        // 手动配置HCCL_STUCK_DETECT_TIME也不允许小于60s的值不能小于60 小于的话设置为60
        if (g_externalInput.stuckDetectTime < HCCL_STUCK_DETECT_TIME_MIN) {
            g_externalInput.stuckDetectTime = HCCL_STUCK_DETECT_TIME_MIN;
        }
        // HCCL_STUCK_DETECT_TIME如果大于HCCL_EXEC_TIMEOUT, 设置为HCCL_EXEC_TIMEOUT
        if (g_externalInput.stuckDetectTime > g_externalInput.execTimeOut) {
            g_externalInput.stuckDetectTime = g_externalInput.execTimeOut;
        }
        // HCCL_EXEC_TIMEOUT配置小于60s, HCCL_STUCK_DETECT_TIME也不允许小于60s
        if (g_externalInput.stuckDetectTime < HCCL_STUCK_DETECT_TIME_MIN &&
            g_externalInput.execTimeOut <= HCCL_STUCK_DETECT_TIME_MIN) {
            g_externalInput.stuckDetectTime = HCCL_STUCK_DETECT_TIME_MIN;
        }
        HCCL_RUN_INFO("HCCL_STUCK_DETECT_TIME set by environment to [%s], process stuck detect time is[%d]s",
            detectTimeEnv.c_str(), g_externalInput.stuckDetectTime);
    } else {
        g_externalInput.stuckDetectTime = g_externalInput.execTimeOut / HCCL_STUCK_DETECT_TIME_BASE;
        // 检测周期最小是60S
        if (g_externalInput.stuckDetectTime < HCCL_STUCK_DETECT_TIME_MIN) {
            g_externalInput.stuckDetectTime = HCCL_STUCK_DETECT_TIME_MIN;
        }
        HCCL_RUN_INFO("HCCL_STUCK_DETECT_TIME is set default [%d]s.", g_externalInput.stuckDetectTime);
    }
    return HCCL_SUCCESS;
}

HcclResult ParseRetryParams()
{
#ifndef CCL_KERNEL_AICPU
    std::string retryParams = SalGetEnv("HCCL_OP_RETRY_PARAMS");
    if (retryParams == "EmptyString") {
        HCCL_RUN_INFO("HCCL_OP_RETRY_PARAMS is not set, default value MaxCnt is %u, HoldTime is %u, "\
            "IntervalTime is %u",
            HCCL_RETRY_MAXCNT_DEFAULT, HCCL_RETRY_HOLD_TIME_DEFAULT, HCCL_RETRY_INTERVAL_DEFAULT);
        return HCCL_SUCCESS;
    }
    u32 maxcnt = 0;
    u32 holdtime = 0;
    u32 intervaltime = 0;
    int ret = 0;
    ret = sscanf_s(retryParams.c_str(), "MaxCnt:%u, HoldTime:%u, IntervalTime:%u",
        &maxcnt, &holdtime, &intervaltime);
    /* 三个参数全部解析成功，返回值为3，否则不等于3 */
    if ((ret != 3) || (maxcnt > HCCL_RETRY_MAXCNT_MAX) || (maxcnt < HCCL_RETRY_MAXCNT_MIN)
        || (holdtime > HCCL_RETRY_HLOD_TIME_MAX) || (intervaltime > HCCL_RETRY_INTERVAL_MAX)) {
        HCCL_ERROR("[Parse][RetryParams]fail, HCCL_OP_RETRY_PARAMS: %s is invalid, format must be: "\
            "MaxCnt:cnt,HoldTime:time,IntervalTime:time, cnt range is [1, 10], time range is [0, 60000].",
            retryParams.c_str());
        return HCCL_E_PARA;
    }
    g_externalInput.retryMaxCnt = maxcnt;
    g_externalInput.retryHoldTime = holdtime;
    g_externalInput.retryIntervalTime = intervaltime;

    HCCL_RUN_INFO("HCCL_OP_RETRY_PARAMS is set, MaxCnt is %u, HoldTime is %u, IntervalTime is %u.",
        maxcnt, holdtime, intervaltime);
#endif
    return HCCL_SUCCESS;
}

HcclResult ParseLogicSuperPodId()
{
    std::string logicSuperPodId = SalGetEnv("HCCL_LOGIC_SUPERPOD_ID");
    if (logicSuperPodId == "EmptyString") {
        HCCL_RUN_INFO("HCCL_LOGIC_SUPERPOD_ID is not set, default value[%s]", g_externalInput.logicSuperPodId.c_str());
        return HCCL_SUCCESS;
    }

    // 校验环境变量长度
    bool isEnvLenValid = CheckEnvLen(logicSuperPodId.c_str(), MAX_LEN_OF_LOGIC_SUPER_ID);
    CHK_PRT_RET(!isEnvLenValid,
        HCCL_ERROR("[Parse][LogicSuperPodId]Invalid HCCL_LOGIC_SUPERPOD_ID env len, len is bigger than [%u].",
        MAX_LEN_OF_LOGIC_SUPER_ID), HCCL_E_PARA);

    g_externalInput.logicSuperPodId = logicSuperPodId;
    HCCL_RUN_INFO("HCCL_LOGIC_SUPERPOD_ID set by environment to [%s]", g_externalInput.logicSuperPodId.c_str());
    return HCCL_SUCCESS;
}

HcclResult SetIncreSaveExecTimeOut(const s32 execTimeout)
{
    if (execTimeout == -1) {
        g_externalInput.increSaveExecTimeOut = execTimeout;
    } else {
        g_externalInput.increSaveExecTimeOut = g_externalInput.execTimeOut;
    }

    HCCL_RUN_INFO("setIncreSaveExecTimeOut execTimeout[%d] increSaveExecTimeOut[%d]",
        execTimeout, g_externalInput.increSaveExecTimeOut);
    return HCCL_SUCCESS;
}

const u32& GetExternalInputHcclIfBasePort()
{
    return g_externalInput.hcclIfBasePort;
}

const u32& GetExternalInputRdmaTrafficClass()
{
    return g_externalInput.rdmaTrafficClass;
}

const u32& GetExternalInputRdmaServerLevel()
{
    return g_externalInput.rdmaServerLevel;
}

const u32& GetExternalInputRdmaTimeOut()
{
    return g_externalInput.rdmaTimeOut;
}

const u32& GetExternalInputRdmaRetryCnt()
{
    return g_externalInput.rdmaRetryCnt;
}

const u32& GetExternalInputTaskExceptionSwitch()
{
    return g_externalInput.taskExceptionSwitch;
}

const u32& GetExternalInputIntraRoceSwitch()
{
    return g_externalInput.intraRoceSwitch;
}

const u32& GetExternalInputHcclEnableWhitelist()
{
    return g_externalInput.enableWhitelist;
}

const u32& GetExternalInputHcclHighPerfEnable()
{
    return g_externalInput.highPerfEnable;
}

const std::string& GetExternalInputHcclWhiteListFile()
{
    return g_externalInput.hcclWhiteListFile;
}

const std::string& GetExternalInputProfilingOption()
{
    return g_externalInput.profilingOption;
}

const std::string& GetExternalInputCannVersion()
{
    return g_externalInput.cannVersion;
}

const s32& GetExternalInputHcclExecTimeOut()
{
    return g_externalInput.execTimeOut;
}

const s32& GetExternalInputStuckDetectTime()
{
    return g_externalInput.stuckDetectTime;
}

const s32& GetExternalInputHcclLinkTimeOut()
{
    return g_externalInput.linkTimeOut;
}

const s32& GetExternalInputHcclSocketFamily()
{
    return g_externalInput.hcclSocketFamily;
}

const bool& GetExternalInputProfilingMode()
{
    return g_externalInput.profilingMode;
}

const bool& GetExternalInputHcclDeviceNicDisable()
{
    return g_externalInput.hcclDeviceNicDisable;
}

const bool& GetExternalInputHcclHostRdmaEnable()
{
    return g_externalInput.hcclHostRdmaEnable;
}

const bool& GetExternalInputHcclIsTcpMode()
{
    return g_externalInput.isTcpMode;
}

const bool& GetExternalInputHcclDumpDebug()
{
    return g_externalInput.dumpDebug;
}

const bool& GetExternalInputHcclEnableFfts()
{
    return g_externalInput.enableFfts;
}

const bool& GetExternalInputHcclDeterministic()
{
    return g_externalInput.hcclDeterministic;
}

const bool& GetExternalInputHcclEnablePipline()
{
    return g_externalInput.enablePipline;
}

const bool& GetExternalInputHcclEnableEntryLog()
{
    return g_externalInput.enableEntryLog;
}

const bool& GetExternalInputInterHccsDisable()
{
    return g_externalInput.interHccsDisable;
}

const bool& GetExternalInputInterVnicDisable()
{
    return g_externalInput.interVnicDisable;
}

const u64& GetExternalInputCCLBuffSize()
{
    return g_externalInput.cclBufferSize;
}

const HcclExecTimeoutSet& GetExternalInputHcclExecTimeoutSet()
{
    return g_externalInput.execTimeOutSet;
}

const hccl::HcclIpAddress& GetExternalInputHcclControlIfIp()
{
    return g_externalInput.hcclControlIfIp;
}

const HcclSocketIfName& GetExternalInputHcclSocketIfName()
{
    return g_externalInput.hcclSocketIfName;
}

const bool& GetSpecificAlgoMode()
{
    return g_externalInput.specificAlgoMode;
}

const std::vector<HcclAlgoType> GetExternalInputHcclAlgoConfig(HcclCMDType opType)
{
    return g_externalInput.hcclAlgoConfig[opType];
}

const u32 GetExternalInputQpsPerConnection()
{
    return g_externalInput.qpsPerConnection;
}

const u32 GetExternalInputMultiQpThreshold()
{
    return g_externalInput.multiQpThreshold;
}

const ProtocolType& GetExternalInputProtocolType()
{
    return g_externalInput.protocolType;
}

const MasterInfo& GetExternalInputMasterInfo()
{
    return g_externalInput.masterInfo;
}

const bool& GetExternalInputHcclAicpuUnfold()
{
    return g_externalInput.aicpuUnfold;
}

const bool& GetExternalInputHcclAivMode()
{
    return g_externalInput.aivMode;
}

const u32& GetExternalInputMc2DebugMode()
{
    return g_externalInput.mc2DebugMode;
}

const u32& GetExternalInputLogConfig()
{
    return g_externalInput.logConfig;
}

const bool& GetRemoteIsHdc()
{
    return g_externalInput.remoteIsHdc;
}

const bool& GetExternalInputEnableRdmaSdmaConcurrent()
{
    return g_externalInput.enableRdmaSdmaConcurrent;
}

const bool& GetExternalInputIntraServerRetryEnable()
{
    return g_externalInput.hcclRetryConfig[HCCL_RETRY_ENABLE_LEVEL_0];
}

const bool& GetExternalInputInterServerRetryEnable()
{
    return g_externalInput.hcclRetryConfig[HCCL_RETRY_ENABLE_LEVEL_1];
}

const bool& GetExternalInputInterSuperPodRetryEnable()
{
    return g_externalInput.hcclRetryConfig[HCCL_RETRY_ENABLE_LEVEL_2];
}

const u32& GetExternalInputHcclSendCqDepth()
{
    return g_externalInput.hcclSendCqDepth;
}

const bool& GetExternalInputHcclDftLevel()
{
    return g_externalInput.hcclDftEnable;
}

const bool& GetExternalInputOpCounter()
{
    return g_externalInput.opCounterEnable;
}

const u32& GetExternalInputRetryMaxCnt()
{
    return g_externalInput.retryMaxCnt;
}

const u32& GetExternalInputRetryHoldTime()
{
    return g_externalInput.retryHoldTime;
}

const u32& GetExternalInputRetryIntervalTime()
{
    return g_externalInput.retryIntervalTime;
}

const std::string& GetExternalInputLogicSuperPodId()
{
    return g_externalInput.logicSuperPodId;
}

const bool& GetExternalInputRdmaFastPost()
{
    return g_externalInput.rdmaFastPost;
}

const std::string& GetExternalInputQpSrcPortConfigPath()
{
    return g_externalInput.multiQpSrcPortConfigPath;
}

const s32& GetIncreSaveExecTimeOut()
{
    return g_externalInput.increSaveExecTimeOut;
}

const u64& GetProfConfig()
{
    return g_externalInput.profConfig;
}